Compare commits
10 commits
f3293008b0
...
fa1788d822
Author | SHA1 | Date | |
---|---|---|---|
|
fa1788d822 | ||
|
e6b1d2755f | ||
|
6f15838d24 | ||
|
e3ea3e9044 | ||
|
f571d32d60 | ||
|
576298fe09 | ||
|
d9bea6d801 | ||
|
c2f8036fd3 | ||
|
d7f81842a4 | ||
|
7445f7cf90 |
58 changed files with 2045 additions and 291 deletions
README.md
angular
apache-php
dev-envs.pngdjango
fastapi
flask-redis
flask
icon_devenvs.svgicon_wasm.svgnginx-aspnet-mysql
nginx-flask-mongo
nginx-flask-mysql
nginx-golang-mysql
nginx-golang-postgres
nginx-golang
official-documentation-samples
open_in_new.svgpihole-cloudflared-DoH
postgresql-pgadmin
react-express-mongodb
react-express-mysql
react-java-mysql
react-nginx
react-rust-postgres
sparkjava-mysql
sparkjava
spring-postgres
traefik-golang
vuejs
wasmedge-kafka-mysql
wasmedge-mysql-nginx
107
README.md
107
README.md
|
@ -6,8 +6,7 @@
|
|||
|
||||
These samples provide a starting point for how to integrate different services using a Compose file and to manage their deployment with Docker Compose.
|
||||
|
||||
> **Note:**
|
||||
>
|
||||
> **Note**
|
||||
> The following samples are intended for use in local development environments such as project setups, tinkering with software stacks, etc. These samples must not be deployed in production environments.
|
||||
|
||||
<!--lint disable awesome-toc-->
|
||||
|
@ -18,56 +17,71 @@ These samples provide a starting point for how to integrate different services u
|
|||
- [Basic setups for different platforms (not production ready - useful for personal use)](#basic-setups-for-different-platforms-not-production-ready---useful-for-personal-use).
|
||||
|
||||
## Samples of Docker Compose applications with multiple integrated services
|
||||
- [`ASP.NET / MS-SQL`](https://github.com/docker/awesome-compose/tree/master/aspnet-mssql) - Sample ASP.NET core application
|
||||
|
||||
<a href="https://docs.docker.com/desktop/dev-environments/"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a> Icon indicates Sample is compatible with [Docker Dev Environments](https://docs.docker.com/desktop/dev-environments/) in Docker Desktop version 4.10 or later.
|
||||
|
||||
<a href="https://docs.docker.com/desktop/wasm/"><img src="icon_wasm.svg" alt="Docker + wasm" height="30" align="top"/></a> Icon indicates Sample is compatible with [Docker+Wasm](https://docs.docker.com/desktop/wasm/).
|
||||
|
||||
- [`ASP.NET / MS-SQL`](aspnet-mssql) - Sample ASP.NET core application
|
||||
with MS SQL server database.
|
||||
- [`Elasticsearch / Logstash / Kibana`](https://github.com/docker/awesome-compose/tree/master/elasticsearch-logstash-kibana) - Sample Elasticsearch, Logstash, and Kibana stack.
|
||||
- [`Go / NGINX / MySQL`](https://github.com/docker/awesome-compose/tree/master/nginx-golang-mysql) - Sample Go application
|
||||
with an Nginx proxy and a MySQL database.
|
||||
- [`Go / NGINX / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/nginx-golang-postgres) - Sample Go
|
||||
application with an Nginx proxy and a PostgreSQL database.
|
||||
- [`Java Spark / MySQL`](https://github.com/docker/awesome-compose/tree/master/sparkjava-mysql) - Sample Java application and
|
||||
a MySQL database.
|
||||
- [`NGINX / ASP.NET / MySQL`](https://github.com/docker/awesome-compose/tree/master/nginx-aspnet-mysql) - Sample Nginx reverse proxy with an C# backend using ASP.NET
|
||||
- [`NGINX / Flask / MongoDB`](https://github.com/docker/awesome-compose/tree/master/nginx-flask-mongo) - Sample Python/Flask
|
||||
application with Nginx proxy and a Mongo database.
|
||||
- [`NGINX / Flask / MySQL`](https://github.com/docker/awesome-compose/tree/master/nginx-flask-mysql) - Sample Python/Flask application with an Nginx proxy and a MySQL database.
|
||||
- [`NGINX / Node.js / Redis`](https://github.com/docker/awesome-compose/tree/master/nginx-nodejs-redis) - Sample Node.js application with Nginx proxy and a Redis database
|
||||
- [`NGINX / Go`](https://github.com/docker/awesome-compose/tree/master/nginx-golang) - Sample Nginx proxy with a Go backend.
|
||||
- [`NGINX / WSGI / Flask`](https://github.com/docker/awesome-compose/tree/master/nginx-wsgi-flask) - Sample Nginx reverse proxy with a Flask backend using WSGI.
|
||||
- [`PostgreSQL / pgAdmin`](https://github.com/docker/awesome-compose/tree/master/postgresql-pgadmin) - Sample setup for postgreSQL database with pgAdmin web interface
|
||||
- [`Python / Flask / Redis`](https://github.com/docker/awesome-compose/tree/master/flask-redis) - Sample Python/Flask and a Redis database
|
||||
- [`React / Spring / MySQL`](https://github.com/docker/awesome-compose/tree/master/react-java-mysql) - Sample React
|
||||
application with a Spring backend and a MySQL database.
|
||||
- [`React / Express / MySQL`](https://github.com/docker/awesome-compose/tree/master/react-express-mysql) - Sample React
|
||||
application with a Node.js backend and a MySQL database.
|
||||
- [`React / Express / MongoDB`](https://github.com/docker/awesome-compose/tree/master/react-express-mongodb) - Sample React
|
||||
application with a Node.js backend and a Mongo database.
|
||||
- [`React / Rust / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/react-rust-postgres) - Sample React
|
||||
application with a Rust backend and a Postgres database.
|
||||
- [`React / Nginx`](https://github.com/docker/awesome-compose/tree/master/react-nginx) - Sample React application with Nginx.
|
||||
- [`Spring / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/spring-postgres) - Sample Java application
|
||||
with Spring framework and a Postgres database.
|
||||
- [`Elasticsearch / Logstash / Kibana`](elasticsearch-logstash-kibana) - Sample Elasticsearch, Logstash, and Kibana stack.
|
||||
- [`Go / NGINX / MySQL`](nginx-golang-mysql) - Sample Go application
|
||||
with an Nginx proxy and a MySQL database. <a href="nginx-golang-mysql"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Go / NGINX / PostgreSQL`](nginx-golang-postgres) - Sample Go
|
||||
application with an Nginx proxy and a PostgreSQL database. <a href="nginx-golang-postgres"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Java Spark / MySQL`](sparkjava-mysql) - Sample Java application and
|
||||
a MySQL database. <a href="sparkjava-mysql"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`NGINX / ASP.NET / MySQL`](nginx-aspnet-mysql) - Sample Nginx reverse proxy with an C# backend using ASP.NET <a href="nginx-aspnet-mysql"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`NGINX / Flask / MongoDB`](nginx-flask-mongo) - Sample Python/Flask
|
||||
application with Nginx proxy and a Mongo database. <a href="nginx-flask-mongo"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`NGINX / Flask / MySQL`](nginx-flask-mysql) - Sample Python/Flask application with an Nginx proxy and a MySQL database.
|
||||
- [`NGINX / Node.js / Redis`](nginx-nodejs-redis) - Sample Node.js application with Nginx proxy and a Redis database
|
||||
- [`NGINX / Go`](nginx-golang) - Sample Nginx proxy with a Go backend. <a href="nginx-golang"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`NGINX / WSGI / Flask`](nginx-wsgi-flask) - Sample Nginx reverse proxy with a Flask backend using WSGI.
|
||||
- [`PostgreSQL / pgAdmin`](postgresql-pgadmin) - Sample setup for postgreSQL database with pgAdmin web interface
|
||||
- [`Python / Flask / Redis`](flask-redis) - Sample Python/Flask and a Redis database <a href="flask-redis"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`React / Spring / MySQL`](react-java-mysql) - Sample React
|
||||
application with a Spring backend and a MySQL database. <a href="react-java-mysql"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`React / Express / MySQL`](react-express-mysql) - Sample React
|
||||
application with a Node.js backend and a MySQL database. <a href="react-express-mysql"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`React / Express / MongoDB`](react-express-mongodb) - Sample React
|
||||
application with a Node.js backend and a Mongo database. <a href="react-express-mongodb"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`React / Rust / PostgreSQL`](react-rust-postgres) - Sample React
|
||||
application with a Rust backend and a Postgres database. <a href="react-rust-postgres"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`React / Nginx`](react-nginx) - Sample React application with Nginx. <a href="react-nginx"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Spring / PostgreSQL`](spring-postgres) - Sample Java application
|
||||
with Spring framework and a Postgres database. <a href="spring-postgres"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`WasmEdge / MySQL / Nginx`](wasmedge-mysql-nginx) - Sample Wasm-based web application with a static HTML frontend, using a MySQL (MariaDB) database. The frontend connects to a Wasm microservice written in Rust, that runs using the WasmEdge runtime. <a href="wasmedge-mysql-nginx"><img src="icon_wasm.svg" alt="Compatible with Docker+wasm" height="30" align="top"/></a>
|
||||
- [`WasmEdge / Kafka / MySQL`](wasmedge-kafka-mysql) - Sample Wasm-based microservice that subscribes to a Kafka (Redpanda) queue topic, and transforms and saves any incoming message into a MySQL (MariaDB) database. <a href="wasmedge-kafka-mysql"><img src="icon_wasm.svg" alt="Compatible with Docker+wasm" height="30" align="top"/></a>
|
||||
|
||||
## Single service samples
|
||||
- [`Angular`](https://github.com/docker/awesome-compose/tree/master/angular)
|
||||
- [`Spark`](https://github.com/docker/awesome-compose/tree/master/sparkjava)
|
||||
- [`VueJS`](https://github.com/docker/awesome-compose/tree/master/vuejs)
|
||||
- [`Flask`](https://github.com/docker/awesome-compose/tree/master/flask)
|
||||
- [`PHP`](https://github.com/docker/awesome-compose/tree/master/apache-php)
|
||||
- [`Traefik`](https://github.com/docker/awesome-compose/tree/master/traefik-golang)
|
||||
- [`Django`](https://github.com/docker/awesome-compose/tree/master/django)
|
||||
|
||||
<a href="https://docs.docker.com/desktop/dev-environments/"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a> Icon indicates Sample is compatible with [Docker Dev Environments](https://docs.docker.com/desktop/dev-environments/) in Docker Desktop version 4.10 or later.
|
||||
|
||||
- [`Angular`](angular) <a href="angular"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Spark`](sparkjava) <a href="sparkjava"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`VueJS`](vuejs) <a href="vuejs"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Flask`](flask) <a href="flask"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`PHP`](apache-php) <a href="apache-php"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Traefik`](traefik-golang) <a href="traefik-golang"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Django`](django) <a href="django"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
- [`Minecraft server`](https://github.com/docker/awesome-compose/tree/master/minecraft)
|
||||
- [`Plex`](https://github.com/docker/awesome-compose/tree/master/plex)
|
||||
- [`Portainer`](https://github.com/docker/awesome-compose/tree/master/portainer)
|
||||
- [`Wireguard`](https://github.com/docker/awesome-compose/tree/master/wireguard)
|
||||
## Basic setups for different platforms (not production ready - useful for personal use)
|
||||
- [`Gitea / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/gitea-postgres)
|
||||
- [`Nextcloud / PostgreSQL`](https://github.com/docker/awesome-compose/tree/master/nextcloud-postgres)
|
||||
- [`Nextcloud / Redis / MariaDB`](https://github.com/docker/awesome-compose/tree/master/nextcloud-redis-mariadb)
|
||||
- [`Pi-hole / cloudflared`](https://github.com/docker/awesome-compose/tree/master/pihole-cloudflared-DoH) - Sample Pi-hole setup with use of DoH cloudflared service
|
||||
- [`Prometheus / Grafana`](https://github.com/docker/awesome-compose/tree/master/prometheus-grafana)
|
||||
- [`Wordpress / MySQL`](https://github.com/docker/awesome-compose/tree/master/wordpress-mysql)
|
||||
- [`FastAPI`](fastapi) <a href="fastapi#use-with-docker-development-environments"><img src="icon_devenvs.svg" alt="Use with Docker Dev Environments" height="30" align="top"/></a>
|
||||
|
||||
## Basic setups for different platforms (not production ready - useful for personal use)
|
||||
|
||||
- [`Gitea / PostgreSQL`](gitea-postgres)
|
||||
- [`Nextcloud / PostgreSQL`](nextcloud-postgres)
|
||||
- [`Nextcloud / Redis / MariaDB`](nextcloud-redis-mariadb)
|
||||
- [`Pi-hole / cloudflared`](pihole-cloudflared-DoH) - Sample Pi-hole setup with use of DoH cloudflared service
|
||||
- [`Prometheus / Grafana`](prometheus-grafana)
|
||||
- [`Wordpress / MySQL`](wordpress-mysql)
|
||||
|
||||
<!--lint disable awesome-toc-->
|
||||
|
||||
## Getting started
|
||||
|
||||
These instructions will get you through the bootstrap phase of creating and
|
||||
|
@ -99,6 +113,11 @@ To stop and remove all containers of the sample application run:
|
|||
```console
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Quickstart guides
|
||||
|
||||
In addition to all the ready to run Compose samples listed above the folder [official-documentation-samples](official-documentation-samples/README.md) contains quickstart guides. Each of these step by step guides explain which files need to be created to build and run a Docker Compose application.
|
||||
|
||||
<!--lint disable awesome-toc-->
|
||||
## Contribute
|
||||
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/angular)
|
||||
|
||||
### Angular service
|
||||
|
||||
Project structure:
|
||||
|
@ -65,14 +72,3 @@ Stop and remove the container
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/angular
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/apache-php)
|
||||
|
||||
### PHP application with Apache2
|
||||
|
||||
Project structure:
|
||||
|
@ -54,14 +61,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/apache-php
|
||||
```
|
||||
|
|
BIN
dev-envs.png
BIN
dev-envs.png
Binary file not shown.
Before ![]() (image error) Size: 158 KiB |
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/django)
|
||||
|
||||
### Django application in dev mode
|
||||
|
||||
Project structure:
|
||||
|
@ -50,10 +57,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly the web service inside a container, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/django`
|
||||
|
||||

|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/fastapi)
|
||||
|
||||
### Python/FastAPI application
|
||||
|
||||
Project structure:
|
||||
|
@ -51,14 +58,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/fastapi
|
||||
```
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/flask-redis)
|
||||
|
||||
### Python/Flask application using a Redis database
|
||||
|
||||
Project structure:
|
||||
|
@ -80,14 +86,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/flask-redis
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/flask)
|
||||
|
||||
### Python/Flask application
|
||||
|
||||
Project structure:
|
||||
|
@ -55,14 +62,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/flask
|
||||
```
|
||||
|
|
8
icon_devenvs.svg
Normal file
8
icon_devenvs.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="#54D1B0">
|
||||
<path
|
||||
d="M5.023 14.4711H5.0127V9.71269L11.7075 12.5098C11.7166 12.5136 11.7257 12.5172 11.7348 12.5207C11.8226 12.5622 11.9289 12.583 12.042 12.581C12.1551 12.583 12.2615 12.5622 12.3492 12.5207C12.3584 12.5172 12.3675 12.5136 12.3765 12.5098L19.0125 9.73729V14.4711H19.0021C19.009 14.5093 19.0125 14.5484 19.0125 14.588C19.0125 14.6005 19.0121 14.6128 19.0114 14.6251C18.9973 14.8804 18.8378 15.1069 18.5967 15.2117L12.2968 17.9413C12.2058 17.9802 12.1092 18 12.0126 18C11.9153 18 11.8187 17.9802 11.7277 17.9413L5.42779 15.2117C5.19236 15.1091 5.03453 14.8897 5.01479 14.641C5.0134 14.6234 5.0127 14.6058 5.0127 14.588C5.0127 14.5484 5.01621 14.5093 5.023 14.4711ZM18.7272 8.86192C18.6871 8.83329 18.6435 8.80857 18.5969 8.78842L12.297 6.05886C12.1157 5.98038 11.9092 5.98038 11.7279 6.05886L5.42802 8.78842C5.39 8.80489 5.354 8.82442 5.32029 8.84664L12.042 11.655L18.7272 8.86192Z"
|
||||
/>
|
||||
<path
|
||||
d="M6.06462 6.95773C5.93949 6.78761 5.71282 6.7275 5.51984 6.81327L3.54841 7.68946C3.27307 7.81183 3.08001 8.06184 3.02741 8.35276C3.02677 8.3563 3.02369 8.3589 3.02009 8.3589V8.3589C3.01601 8.3589 3.0127 8.36221 3.0127 8.3663V15.2024C3.0127 15.2058 3.01542 15.2085 3.01877 15.2085V15.2085C3.02254 15.2085 3.0254 15.2119 3.02478 15.2156C3.01681 15.2638 3.0127 15.3132 3.0127 15.3632C3.0127 15.3867 3.01361 15.41 3.01539 15.4332C3.04085 15.7623 3.24444 16.0526 3.54812 16.1884L11.6742 19.8C11.7916 19.8515 11.9161 19.8777 12.0416 19.8777C12.1663 19.8777 12.2909 19.8515 12.4082 19.8L14.2808 18.9677C14.5198 18.8615 14.5994 18.5615 14.4444 18.3507V18.3507C14.3306 18.1959 14.1244 18.1411 13.9487 18.2188L12.3373 18.9315C12.2334 18.9769 12.123 19 12.0125 19C11.9013 19 11.791 18.9769 11.687 18.9315L4.48709 15.747C4.21802 15.6273 4.03764 15.3713 4.01509 15.0811C4.0135 15.0607 4.0127 15.0401 4.0127 15.0194C4.0127 14.9753 4.01634 14.9318 4.0234 14.8893C4.02395 14.886 4.02142 14.883 4.01808 14.883V14.883C4.0151 14.883 4.0127 14.8806 4.0127 14.8776V8.84998C4.0127 8.84636 4.01563 8.84342 4.01925 8.84342V8.84342C4.02244 8.84342 4.02516 8.84112 4.02573 8.83799C4.07235 8.58148 4.2434 8.36105 4.48735 8.25315L5.8843 7.63529C6.14719 7.51901 6.23494 7.18929 6.06462 6.95773V6.95773ZM18.2951 16.8352C18.1416 16.6265 18.2207 16.3293 18.4577 16.2245L19.5372 15.747C19.8128 15.6247 19.9951 15.3604 20.0112 15.0627C20.012 15.0483 20.0124 15.0339 20.0124 15.0194C20.0124 14.9753 20.0088 14.9318 20.0017 14.8893C20.0012 14.886 20.0037 14.883 20.007 14.883V14.883C20.01 14.883 20.0124 14.8806 20.0124 14.8776V9.00055L20.0127 8.98001L20.0126 8.96926L20.0124 8.95947V8.84972C20.0124 8.84624 20.0096 8.84342 20.0061 8.84342V8.84342C20.0031 8.84342 20.0005 8.84122 19.9999 8.83821C19.9534 8.5816 19.7822 8.36108 19.5375 8.25315L12.3376 5.06867C12.1304 4.97711 11.8944 4.97711 11.6872 5.06867L10.4765 5.60419C10.2817 5.69035 10.0532 5.62954 9.92697 5.45796V5.45796C9.75514 5.22434 9.84334 4.89172 10.1083 4.77394L11.6745 4.07788C11.9083 3.97404 12.1747 3.97404 12.4085 4.07788L20.5346 7.68946C20.8108 7.81187 21.004 8.06198 21.0565 8.35301C21.0571 8.35641 21.0601 8.3589 21.0635 8.3589V8.3589C21.0675 8.3589 21.0706 8.36208 21.0706 8.366V8.49051L21.0708 8.50161L21.0709 8.5138C21.0709 8.52159 21.0708 8.52935 21.0706 8.5371V15.2024C21.0706 15.2058 21.0679 15.2085 21.0646 15.2085V15.2085C21.0608 15.2085 21.0579 15.2119 21.0585 15.2156C21.0665 15.2638 21.0706 15.3132 21.0706 15.3632C21.0706 15.3796 21.0702 15.396 21.0693 15.4123C21.051 15.75 20.8453 16.0497 20.5343 16.1884L18.7861 16.9654C18.6122 17.0427 18.4079 16.9885 18.2951 16.8352V16.8352Z"
|
||||
/>
|
||||
</svg>
|
After (image error) Size: 3.5 KiB |
13
icon_wasm.svg
Normal file
13
icon_wasm.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<svg id="WA-icon" xmlns="http://www.w3.org/2000/svg" width="144" height="111" viewBox="0 0 1440 1110">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #6f45f9;
|
||||
fill-rule: evenodd;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path id="shape_4" data-name="shape 4" class="cls-1" d="M445,280H651v7s0.437,32.383,29,49c30.515,17.752,62.137,4.583,72-4,10.362-9.017,22.2-23.3,23-45v-7H981V816H445V280ZM569,567h36l24,128,30-128h33l27,128,28-127h35L737,759H702L675,631,646,759H610ZM776,759l46-191h57l55,191H897l-12-42H820l-9,42H776Z" transform="translate(0.594 9.312)"/>
|
||||
<path id="shape_1" data-name="shape 1" class="cls-1" d="M827,685.471l16-71h15l19,71H827Z" transform="translate(0.594 9.312)"/>
|
||||
<path id="shape_3" data-name="shape 3" class="cls-1" d="M323,232.471l-122,54s-32,12.311-32,51v412s-4.458,38.615,29,54,497,221,497,221,22.409,11.15,46,1,116-51,116-51,14.081-5.669,14-22c-0.088-17.6-16.3-33.023-36-24s-96,43-96,43-17.573,10.1-37,2-449-198-449-198-24-11.257-24-40v-374a42.353,42.353,0,0,1,25-38c25.972-12.225,88-39,88-39s18-5.765,18-26C360,237.118,338.709,225.966,323,232.471Zm284-127,93-41s19.94-8.9,51,5,485,216,485,216,34,14.168,34,51v422s0.85,30.084-26,43-116,53-116,53-14.98,4.522-25-7-8.79-32.833,5-39,67-29,67-29l8-4s23-12.024,23-46v-369s1.61-26.142-28-39-437-194-437-194-21.48-9.931-40-2-77,34-77,34-22.162,7.988-33-8S584.324,115.515,607,105.471Z" transform="translate(0.594 9.312)"/>
|
||||
</svg>
|
After (image error) Size: 1.4 KiB |
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-aspnet-mysql)
|
||||
|
||||
### ASP.NET server with an Nginx proxy and a MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -75,14 +82,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-aspnet-mysql
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-flask-mongo)
|
||||
|
||||
### Python/Flask application with Nginx proxy and a Mongo database
|
||||
|
||||
Project structure:
|
||||
|
@ -69,14 +76,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-flask-mongo
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-flask-mysql)
|
||||
|
||||
### Python/Flask with Nginx proxy and MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -77,14 +84,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-flask-mysql
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-golang-mysql)
|
||||
|
||||
### Go server with an Nginx proxy and a MariaDB/MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -90,14 +97,3 @@ Stop and remove the containers
|
|||
```shell
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-golang-mysql
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-golang-postgres)
|
||||
|
||||
### Go server with an Nginx proxy and a Postgres database
|
||||
|
||||
Project structure:
|
||||
|
@ -80,14 +87,3 @@ Stop and remove the containers
|
|||
```shell
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-golang-postgres
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/nginx-golang)
|
||||
|
||||
### NGINX proxy with Go backend
|
||||
|
||||
Project structure:
|
||||
|
@ -83,14 +90,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/nginx-golang
|
||||
```
|
||||
|
|
28
official-documentation-samples/README.md
Normal file
28
official-documentation-samples/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Sample apps with Compose
|
||||
|
||||
The following samples show the various aspects of how to work with Docker
|
||||
Compose. As a prerequisite, be sure to [install Docker Compose](https://docs.docker.com/compose/install/)
|
||||
if you have not already done so.
|
||||
|
||||
## Key concepts these samples cover
|
||||
|
||||
The samples should help you to:
|
||||
|
||||
- define services based on Docker images using
|
||||
[Compose files](https://docs.docker.com/compose/compose-file/) `docker-compose.yml` files
|
||||
- understand the relationship between `docker-compose.yml` and
|
||||
[Dockerfiles](https://docs.docker.com/engine/reference/builder/)
|
||||
- learn how to make calls to your application services from Compose files
|
||||
|
||||
## Samples tailored to demo Compose
|
||||
|
||||
These samples focus specifically on Docker Compose:
|
||||
|
||||
- [Quickstart: Compose and Django](./django/README.md) - Shows how to use Docker Compose to set up and run a simple Django/PostgreSQL app.
|
||||
|
||||
- [Quickstart: Compose and Rails](./rails/README.md) - Shows how to use
|
||||
Docker Compose to set up and run a Rails/PostgreSQL app.
|
||||
|
||||
- [Quickstart: Compose and WordPress](./wordpress/README.md) - Shows how to
|
||||
use Docker Compose to set up and run WordPress in an isolated environment
|
||||
with Docker containers.
|
286
official-documentation-samples/django/README.md
Normal file
286
official-documentation-samples/django/README.md
Normal file
|
@ -0,0 +1,286 @@
|
|||
# Quickstart: Compose and Django
|
||||
|
||||
This quick-start guide demonstrates how to use Docker Compose to set up and run a simple Django/PostgreSQL app. Before starting,
|
||||
[install Compose](https://docs.docker.com/compose/install/).
|
||||
|
||||
## Define the project components
|
||||
|
||||
For this project, you need to create a Dockerfile, a Python dependencies file,
|
||||
and a `docker-compose.yml` file. (You can use either a `.yml` or `.yaml` extension for this file.)
|
||||
|
||||
1. Create an empty project directory.
|
||||
|
||||
You can name the directory something easy for you to remember. This directory is the context for your application image. The directory should only contain resources to build that image.
|
||||
|
||||
2. Create a new file called `Dockerfile` in your project directory.
|
||||
|
||||
The Dockerfile defines an application's image content via one or more build
|
||||
commands that configure that image. Once built, you can run the image in a
|
||||
container. For more information on `Dockerfile`, see the [Docker user guide](https://docs.docker.com/get-started/)
|
||||
and the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).
|
||||
|
||||
3. Add the following content to the `Dockerfile`.
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM python:3
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
WORKDIR /code
|
||||
COPY requirements.txt /code/
|
||||
RUN pip install -r requirements.txt
|
||||
COPY . /code/
|
||||
```
|
||||
|
||||
This `Dockerfile` starts with a [Python 3 parent image](https://hub.docker.com/r/library/python/tags/3/).
|
||||
The parent image is modified by adding a new `code` directory. The parent image is further modified
|
||||
by installing the Python requirements defined in the `requirements.txt` file.
|
||||
|
||||
4. Save and close the `Dockerfile`.
|
||||
|
||||
5. Create a `requirements.txt` in your project directory.
|
||||
|
||||
This file is used by the `RUN pip install -r requirements.txt` command in your `Dockerfile`.
|
||||
|
||||
6. Add the required software in the file.
|
||||
|
||||
```python
|
||||
Django>=3.0,<4.0
|
||||
psycopg2>=2.8
|
||||
```
|
||||
|
||||
7. Save and close the `requirements.txt` file.
|
||||
|
||||
8. Create a file called `docker-compose.yml` in your project directory.
|
||||
|
||||
The `docker-compose.yml` file describes the services that make your app. In
|
||||
this example those services are a web server and database. The compose file
|
||||
also describes which Docker images these services use, how they link
|
||||
together, any volumes they might need to be mounted inside the containers.
|
||||
Finally, the `docker-compose.yml` file describes which ports these services
|
||||
expose. See the [`docker-compose.yml` reference](https://docs.docker.com/compose/compose-file/) for more
|
||||
information on how this file works.
|
||||
|
||||
9. Add the following configuration to the file.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
image: postgres
|
||||
volumes:
|
||||
- ./data/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
web:
|
||||
build: .
|
||||
command: python manage.py runserver 0.0.0.0:8000
|
||||
volumes:
|
||||
- .:/code
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- POSTGRES_NAME=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
depends_on:
|
||||
- db
|
||||
```
|
||||
|
||||
This file defines two services: The `db` service and the `web` service.
|
||||
|
||||
> Note:
|
||||
>
|
||||
> This uses the build in development server to run your application
|
||||
> on port 8000. Do not use this in a production environment. For more
|
||||
> information, see [Django documentation](https://docs.djangoproject.com/en/3.1/intro/tutorial01/#the-development-server){: target="_blank" rel="noopener" class="_”}.
|
||||
|
||||
10. Save and close the `docker-compose.yml` file.
|
||||
|
||||
## Create a Django project
|
||||
|
||||
In this step, you create a Django starter project by building the image from the build context defined in the previous procedure.
|
||||
|
||||
1. Change to the root of your project directory.
|
||||
|
||||
2. Create the Django project by running the [docker compose run](https://docs.docker.com/engine/reference/commandline/compose_run/)
|
||||
command as follows.
|
||||
|
||||
```console
|
||||
sudo docker compose run web django-admin startproject composeexample .
|
||||
```
|
||||
|
||||
This instructs Compose to run `django-admin startproject composeexample`
|
||||
in a container, using the `web` service's image and configuration. Because
|
||||
the `web` image doesn't exist yet, Compose builds it from the current
|
||||
directory, as specified by the `build: .` line in `docker-compose.yml`.
|
||||
|
||||
Once the `web` service image is built, Compose runs it and executes the
|
||||
`django-admin startproject` command in the container. This command
|
||||
instructs Django to create a set of files and directories representing a
|
||||
Django project.
|
||||
|
||||
3. After the `docker compose` command completes, list the contents of your project.
|
||||
|
||||
```console
|
||||
$ ls -l
|
||||
|
||||
drwxr-xr-x 2 root root composeexample
|
||||
drwxr-xr-x 3 root root data
|
||||
-rw-rw-r-- 1 user user docker-compose.yml
|
||||
-rw-rw-r-- 1 user user Dockerfile
|
||||
-rwxr-xr-x 1 root root manage.py
|
||||
-rw-rw-r-- 1 user user requirements.txt
|
||||
```
|
||||
|
||||
If you are running Docker on Linux, the files `django-admin` created are
|
||||
owned by root. This happens because the container runs as the root user.
|
||||
Change the ownership of the new files.
|
||||
|
||||
Do not change the permission of the data folder where Postgres has its file, otherwise Postgres will not be able to start due to permission issues.
|
||||
|
||||
```console
|
||||
sudo chown -R $USER:$USER composeexample manage.py
|
||||
```
|
||||
|
||||
If you are running Docker on Mac or Windows, you should already
|
||||
have ownership of all files, including those generated by
|
||||
`django-admin`. List the files just to verify this.
|
||||
|
||||
```console
|
||||
$ ls -l
|
||||
|
||||
total 32
|
||||
-rw-r--r-- 1 user staff 145 Feb 13 23:00 Dockerfile
|
||||
drwxr-xr-x 6 user staff 204 Feb 13 23:07 composeexample
|
||||
-rw-r--r-- 1 user staff 159 Feb 13 23:02 docker-compose.yml
|
||||
-rwxr-xr-x 1 user staff 257 Feb 13 23:07 manage.py
|
||||
-rw-r--r-- 1 user staff 16 Feb 13 23:01 requirements.txt
|
||||
```
|
||||
|
||||
### Connect the database
|
||||
|
||||
In this section, you set up the database connection for Django.
|
||||
|
||||
1. In your project directory, edit the `composeexample/settings.py` file.
|
||||
|
||||
2. Replace the `DATABASES = ...` with the following:
|
||||
|
||||
```python
|
||||
# settings.py
|
||||
|
||||
import os
|
||||
|
||||
[...]
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': os.environ.get('POSTGRES_NAME'),
|
||||
'USER': os.environ.get('POSTGRES_USER'),
|
||||
'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
|
||||
'HOST': 'db',
|
||||
'PORT': 5432,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These settings are determined by the
|
||||
[postgres](https://hub.docker.com/_/postgres) Docker image
|
||||
specified in `docker-compose.yml`.
|
||||
|
||||
3. Save and close the file.
|
||||
|
||||
4. Run the [docker compose up](https://docs.docker.com/engine/reference/commandline/compose_up/) command from the top level directory for your project.
|
||||
|
||||
```console
|
||||
$ docker compose up
|
||||
|
||||
djangosample_db_1 is up-to-date
|
||||
Creating djangosample_web_1 ...
|
||||
Creating djangosample_web_1 ... done
|
||||
Attaching to djangosample_db_1, djangosample_web_1
|
||||
db_1 | The files belonging to this database system will be owned by user "postgres".
|
||||
db_1 | This user must also own the server process.
|
||||
db_1 |
|
||||
db_1 | The database cluster will be initialized with locale "en_US.utf8".
|
||||
db_1 | The default database encoding has accordingly been set to "UTF8".
|
||||
db_1 | The default text search configuration will be set to "english".
|
||||
|
||||
<...>
|
||||
|
||||
web_1 | July 30, 2020 - 18:35:38
|
||||
web_1 | Django version 3.0.8, using settings 'composeexample.settings'
|
||||
web_1 | Starting development server at http://0.0.0.0:8000/
|
||||
web_1 | Quit the server with CONTROL-C.
|
||||
```
|
||||
|
||||
At this point, your Django app should be running at port `8000` on
|
||||
your Docker host. On Docker Desktop for Mac and Docker Desktop for Windows, go
|
||||
to `http://localhost:8000` on a web browser to see the Django
|
||||
welcome page.
|
||||
|
||||

|
||||
|
||||
> Note:
|
||||
>
|
||||
> On certain platforms (Windows 10), you might need to edit `ALLOWED_HOSTS`
|
||||
> inside `settings.py` and add your Docker host name or IP address to the list.
|
||||
> For demo purposes, you can set the value to:
|
||||
>
|
||||
> ```python
|
||||
> ALLOWED_HOSTS = ['*']
|
||||
> ```
|
||||
>
|
||||
> This value is **not** safe for production usage. Refer to the
|
||||
> [Django documentation](https://docs.djangoproject.com/en/1.11/ref/settings/#allowed-hosts) for more information.
|
||||
|
||||
5. List running containers.
|
||||
|
||||
In another terminal window, list the running Docker processes with the `docker ps` or `docker container ls` command.
|
||||
|
||||
```console
|
||||
$ docker ps
|
||||
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
def85eff5f51 django_web "python3 manage.py..." 10 minutes ago Up 9 minutes 0.0.0.0:8000->8000/tcp django_web_1
|
||||
678ce61c79cc postgres "docker-entrypoint..." 20 minutes ago Up 9 minutes 5432/tcp django_db_1
|
||||
```
|
||||
|
||||
6. Shut down services and clean up by using either of these methods:
|
||||
|
||||
* Stop the application by typing `Ctrl-C` in the same shell in where you
|
||||
started it:
|
||||
|
||||
```console
|
||||
Gracefully stopping... (press Ctrl+C again to force)
|
||||
Killing test_web_1 ... done
|
||||
Killing test_db_1 ... done
|
||||
```
|
||||
|
||||
* Or, for a more elegant shutdown, switch to a different shell, and run
|
||||
[docker compose down](https://docs.docker.com/engine/reference/commandline/compose_down/) from the top level of your
|
||||
Django sample project directory.
|
||||
|
||||
```console
|
||||
$ docker compose down
|
||||
|
||||
Stopping django_web_1 ... done
|
||||
Stopping django_db_1 ... done
|
||||
Removing django_web_1 ... done
|
||||
Removing django_web_run_1 ... done
|
||||
Removing django_db_1 ... done
|
||||
Removing network django_default
|
||||
```
|
||||
|
||||
Once you've shut down the app, you can safely remove the Django project directory (for example, `rm -rf django`).
|
||||
|
||||
## More Compose documentation
|
||||
|
||||
* [Docker Compose overview](https://docs.docker.com/compose/)
|
||||
* [Install Docker Compose](https://docs.docker.com/compose/install/)
|
||||
* [Getting Started with Docker Compose](https://docs.docker.com/compose/gettingstarted/)
|
||||
* [Docker Compose Command line reference](https://docs.docker.com/compose/reference/)
|
||||
* [Compose file reference](https://docs.docker.com/compose/compose-file/)
|
||||
* [Awesome Compose Django sample application](../../django/README.md)
|
Binary file not shown.
After ![]() (image error) Size: 18 KiB |
272
official-documentation-samples/rails/README.md
Normal file
272
official-documentation-samples/rails/README.md
Normal file
|
@ -0,0 +1,272 @@
|
|||
# Quickstart: Compose and Rails
|
||||
|
||||
This Quickstart guide shows you how to use Docker Compose to set up and run
|
||||
a Rails/PostgreSQL app. Before starting, [install Compose](https://docs.docker.com/compose/install/).
|
||||
|
||||
## Define the project
|
||||
|
||||
Start by setting up the files needed to build the app. The app will run inside a
|
||||
Docker container containing its dependencies. Defining dependencies is done using
|
||||
a file called `Dockerfile`. To begin with, the Dockerfile consists of:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM ruby:2.5
|
||||
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
|
||||
WORKDIR /myapp
|
||||
COPY Gemfile /myapp/Gemfile
|
||||
COPY Gemfile.lock /myapp/Gemfile.lock
|
||||
RUN bundle install
|
||||
|
||||
# Add a script to be executed every time the container starts.
|
||||
COPY entrypoint.sh /usr/bin/
|
||||
RUN chmod +x /usr/bin/entrypoint.sh
|
||||
ENTRYPOINT ["entrypoint.sh"]
|
||||
EXPOSE 3000
|
||||
|
||||
# Configure the main process to run when running the image
|
||||
CMD ["rails", "server", "-b", "0.0.0.0"]
|
||||
```
|
||||
|
||||
That'll put your application code inside an image that builds a container
|
||||
with Ruby, Bundler and all your dependencies inside it. For more information on
|
||||
how to write Dockerfiles, see the [Docker user guide](https://docs.docker.com/get-started/)
|
||||
and the [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).
|
||||
|
||||
Next, open an editor and create a bootstrap `Gemfile` which just loads Rails. This will be overwritten in a moment by `rails new`.
|
||||
|
||||
```ruby
|
||||
source 'https://rubygems.org'
|
||||
gem 'rails', '~>5'
|
||||
```
|
||||
|
||||
Create an empty `Gemfile.lock` file to build our `Dockerfile`.
|
||||
|
||||
```console
|
||||
$ touch Gemfile.lock
|
||||
```
|
||||
|
||||
Next, provide an entrypoint script to fix a Rails-specific issue that
|
||||
prevents the server from restarting when a certain `server.pid` file pre-exists.
|
||||
This script will be executed every time the container gets started.
|
||||
`entrypoint.sh` consists of:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Remove a potentially pre-existing server.pid for Rails.
|
||||
rm -f /myapp/tmp/pids/server.pid
|
||||
|
||||
# Then exec the container's main process (what's set as CMD in the Dockerfile).
|
||||
exec "$@"
|
||||
```
|
||||
|
||||
Finally, `docker-compose.yml` is where the magic happens. This file describes
|
||||
the services that comprise your app (a database and a web app), how to get each
|
||||
one's Docker image (the database just runs on a pre-made PostgreSQL image, and
|
||||
the web app is built from the current directory), and the configuration needed
|
||||
to link them together and expose the web app's port.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
image: postgres
|
||||
volumes:
|
||||
- ./tmp/db:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_PASSWORD: password
|
||||
web:
|
||||
build: .
|
||||
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
|
||||
volumes:
|
||||
- .:/myapp
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- db
|
||||
```
|
||||
|
||||
> **Tip**
|
||||
>
|
||||
> You can use either a `.yml` or `.yaml` extension for this file.
|
||||
|
||||
### Build the project
|
||||
|
||||
With those files in place, you can now generate the Rails skeleton app
|
||||
using [docker compose run](https://docs.docker.com/engine/reference/commandline/compose_run/):
|
||||
|
||||
```console
|
||||
$ docker compose run --no-deps web rails new . --force --database=postgresql
|
||||
```
|
||||
|
||||
First, Compose builds the image for the `web` service using the `Dockerfile`.
|
||||
The `--no-deps` tells Compose not to start linked services. Then it runs
|
||||
`rails new` inside a new container, using that image. Once it's done, you
|
||||
should have generated a fresh app.
|
||||
|
||||
List the files.
|
||||
|
||||
```console
|
||||
$ ls -l
|
||||
|
||||
total 64
|
||||
-rw-r--r-- 1 vmb staff 222 Jun 7 12:05 Dockerfile
|
||||
-rw-r--r-- 1 vmb staff 1738 Jun 7 12:09 Gemfile
|
||||
-rw-r--r-- 1 vmb staff 4297 Jun 7 12:09 Gemfile.lock
|
||||
-rw-r--r-- 1 vmb staff 374 Jun 7 12:09 README.md
|
||||
-rw-r--r-- 1 vmb staff 227 Jun 7 12:09 Rakefile
|
||||
drwxr-xr-x 10 vmb staff 340 Jun 7 12:09 app
|
||||
drwxr-xr-x 8 vmb staff 272 Jun 7 12:09 bin
|
||||
drwxr-xr-x 14 vmb staff 476 Jun 7 12:09 config
|
||||
-rw-r--r-- 1 vmb staff 130 Jun 7 12:09 config.ru
|
||||
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 db
|
||||
-rw-r--r-- 1 vmb staff 211 Jun 7 12:06 docker-compose.yml
|
||||
-rw-r--r-- 1 vmb staff 184 Jun 7 12:08 entrypoint.sh
|
||||
drwxr-xr-x 4 vmb staff 136 Jun 7 12:09 lib
|
||||
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 log
|
||||
-rw-r--r-- 1 vmb staff 63 Jun 7 12:09 package.json
|
||||
drwxr-xr-x 9 vmb staff 306 Jun 7 12:09 public
|
||||
drwxr-xr-x 9 vmb staff 306 Jun 7 12:09 test
|
||||
drwxr-xr-x 4 vmb staff 136 Jun 7 12:09 tmp
|
||||
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 vendor
|
||||
```
|
||||
|
||||
If you are running Docker on Linux, the files `rails new` created are owned by
|
||||
root. This happens because the container runs as the root user. If this is the
|
||||
case, change the ownership of the new files.
|
||||
|
||||
```console
|
||||
$ sudo chown -R $USER:$USER .
|
||||
```
|
||||
|
||||
If you are running Docker on Mac or Windows, you should already have ownership
|
||||
of all files, including those generated by `rails new`.
|
||||
|
||||
Now that you’ve got a new Gemfile, you need to build the image again. (This, and
|
||||
changes to the `Gemfile` or the Dockerfile, should be the only times you’ll need
|
||||
to rebuild.)
|
||||
|
||||
```console
|
||||
$ docker compose build
|
||||
```
|
||||
|
||||
### Connect the database
|
||||
|
||||
The app is now bootable, but you're not quite there yet. By default, Rails
|
||||
expects a database to be running on `localhost` - so you need to point it at the
|
||||
`db` container instead. You also need to change the database and username to
|
||||
align with the defaults set by the `postgres` image.
|
||||
|
||||
Replace the contents of `config/database.yml` with the following:
|
||||
|
||||
```yaml
|
||||
default: &default
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
host: db
|
||||
username: postgres
|
||||
password: password
|
||||
pool: 5
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
database: myapp_development
|
||||
|
||||
|
||||
test:
|
||||
<<: *default
|
||||
database: myapp_test
|
||||
```
|
||||
|
||||
You can now boot the app with [docker compose up](https://docs.docker.com/engine/reference/commandline/compose_up/).
|
||||
If all is well, you should see some PostgreSQL output:
|
||||
|
||||
```console
|
||||
$ docker compose up
|
||||
|
||||
rails_db_1 is up-to-date
|
||||
Creating rails_web_1 ... done
|
||||
Attaching to rails_db_1, rails_web_1
|
||||
db_1 | PostgreSQL init process complete; ready for start up.
|
||||
db_1 |
|
||||
db_1 | 2018-03-21 20:18:37.437 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
|
||||
db_1 | 2018-03-21 20:18:37.437 UTC [1] LOG: listening on IPv6 address "::", port 5432
|
||||
db_1 | 2018-03-21 20:18:37.443 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
|
||||
db_1 | 2018-03-21 20:18:37.726 UTC [55] LOG: database system was shut down at 2018-03-21 20:18:37 UTC
|
||||
db_1 | 2018-03-21 20:18:37.772 UTC [1] LOG: database system is ready to accept connections
|
||||
```
|
||||
|
||||
Finally, you need to create the database. In another terminal, run:
|
||||
|
||||
```console
|
||||
$ docker compose run web rake db:create
|
||||
Starting rails_db_1 ... done
|
||||
Created database 'myapp_development'
|
||||
Created database 'myapp_test'
|
||||
```
|
||||
|
||||
### View the Rails welcome page!
|
||||
|
||||
That's it. Your app should now be running on port 3000 on your Docker daemon.
|
||||
|
||||
On Docker Desktop for Mac and Docker Desktop for Windows, go to `http://localhost:3000` on a web
|
||||
browser to see the Rails Welcome.
|
||||
|
||||

|
||||
|
||||
### Stop the application
|
||||
|
||||
To stop the application, run [docker compose down](https://docs.docker.com/engine/reference/commandline/compose_down/) in
|
||||
your project directory. You can use the same terminal window in which you
|
||||
started the database, or another one where you have access to a command prompt.
|
||||
This is a clean way to stop the application.
|
||||
|
||||
```console
|
||||
$ docker compose down
|
||||
|
||||
Stopping rails_web_1 ... done
|
||||
Stopping rails_db_1 ... done
|
||||
Removing rails_web_run_1 ... done
|
||||
Removing rails_web_1 ... done
|
||||
Removing rails_db_1 ... done
|
||||
Removing network rails_default
|
||||
|
||||
```
|
||||
|
||||
### Restart the application
|
||||
|
||||
To restart the application run `docker compose up` in the project directory.
|
||||
|
||||
### Rebuild the application
|
||||
|
||||
If you make changes to the Gemfile or the Compose file to try out some different
|
||||
configurations, you need to rebuild. Some changes require only
|
||||
`docker compose up --build`, but a full rebuild requires a re-run of
|
||||
`docker compose run web bundle install` to sync changes in the `Gemfile.lock` to
|
||||
the host, followed by `docker compose up --build`.
|
||||
|
||||
Here is an example of the first case, where a full rebuild is not necessary.
|
||||
Suppose you simply want to change the exposed port on the local host from `3000`
|
||||
in our first example to `3001`. Make the change to the Compose file to expose
|
||||
port `3000` on the container through a new port, `3001`, on the host, and save
|
||||
the changes:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "3001:3000"
|
||||
```
|
||||
|
||||
Now, rebuild and restart the app with `docker compose up --build`.
|
||||
|
||||
Inside the container, your app is running on the same port as before `3000`, but
|
||||
the Rails Welcome is now available on `http://localhost:3001` on your local
|
||||
host.
|
||||
|
||||
## More Compose documentation
|
||||
|
||||
* [Docker Compose overview](https://docs.docker.com/compose/)
|
||||
* [Install Docker Compose](https://docs.docker.com/compose/install/)
|
||||
* [Getting Started with Docker Compose](https://docs.docker.com/compose/gettingstarted/)
|
||||
* [Docker Compose Command line reference](https://docs.docker.com/compose/reference/)
|
||||
* [Compose file reference](https://docs.docker.com/compose/compose-file/)
|
BIN
official-documentation-samples/rails/images/rails-welcome.png
Normal file
BIN
official-documentation-samples/rails/images/rails-welcome.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 334 KiB |
147
official-documentation-samples/wordpress/README.md
Normal file
147
official-documentation-samples/wordpress/README.md
Normal file
|
@ -0,0 +1,147 @@
|
|||
# Quickstart: Compose and WordPress
|
||||
|
||||
You can use Docker Compose to easily run WordPress in an isolated environment
|
||||
built with Docker containers. This quick-start guide demonstrates how to use
|
||||
Compose to set up and run WordPress. Before starting, make sure you have
|
||||
[Compose installed](https://docs.docker.com/compose/install/).
|
||||
|
||||
## Define the project
|
||||
|
||||
1. Create an empty project directory.
|
||||
|
||||
You can name the directory something easy for you to remember.
|
||||
This directory is the context for your application image. The
|
||||
directory should only contain resources to build that image.
|
||||
|
||||
This project directory contains a `docker-compose.yml` file which
|
||||
is complete in itself for a good starter wordpress project.
|
||||
|
||||
>**Tip**: You can use either a `.yml` or `.yaml` extension for
|
||||
this file. They both work.
|
||||
|
||||
2. Change into your project directory.
|
||||
|
||||
For example, if you named your directory `my_wordpress`:
|
||||
|
||||
```console
|
||||
$ cd my_wordpress/
|
||||
```
|
||||
|
||||
3. Create a `docker-compose.yml` file that starts your
|
||||
`WordPress` blog and a separate `MySQL` instance with volume
|
||||
mounts for data persistence:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
db:
|
||||
# We use a mariadb image which supports both amd64 & arm64 architecture
|
||||
image: mariadb:10.6.4-focal
|
||||
# If you really want to use MySQL, uncomment the following line
|
||||
#image: mysql:8.0.27
|
||||
command: '--default-authentication-plugin=mysql_native_password'
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
restart: always
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=somewordpress
|
||||
- MYSQL_DATABASE=wordpress
|
||||
- MYSQL_USER=wordpress
|
||||
- MYSQL_PASSWORD=wordpress
|
||||
expose:
|
||||
- 3306
|
||||
- 33060
|
||||
wordpress:
|
||||
image: wordpress:latest
|
||||
volumes:
|
||||
- wp_data:/var/www/html
|
||||
ports:
|
||||
- 80:80
|
||||
restart: always
|
||||
environment:
|
||||
- WORDPRESS_DB_HOST=db
|
||||
- WORDPRESS_DB_USER=wordpress
|
||||
- WORDPRESS_DB_PASSWORD=wordpress
|
||||
- WORDPRESS_DB_NAME=wordpress
|
||||
volumes:
|
||||
db_data:
|
||||
wp_data:
|
||||
```
|
||||
|
||||
> **Notes**:
|
||||
>
|
||||
* The docker volumes `db_data` and `wordpress_data` persists updates made by WordPress
|
||||
to the database, as well as the installed themes and plugins. [Learn more about docker volumes](https://docs.docker.com/storage/volumes/)
|
||||
>
|
||||
* WordPress Multisite works only on ports `80` and `443`.
|
||||
{: .note-vanilla}
|
||||
|
||||
### Build the project
|
||||
|
||||
Now, run `docker compose up -d` from your project directory.
|
||||
|
||||
This runs [`docker compose up`](https://docs.docker.com/engine/reference/commandline/compose_up/) in detached mode, pulls
|
||||
the needed Docker images, and starts the wordpress and database containers, as shown in
|
||||
the example below.
|
||||
|
||||
```console
|
||||
$ docker compose up -d
|
||||
|
||||
Creating network "my_wordpress_default" with the default driver
|
||||
Pulling db (mysql:5.7)...
|
||||
5.7: Pulling from library/mysql
|
||||
efd26ecc9548: Pull complete
|
||||
a3ed95caeb02: Pull complete
|
||||
<...>
|
||||
Digest: sha256:34a0aca88e85f2efa5edff1cea77cf5d3147ad93545dbec99cfe705b03c520de
|
||||
Status: Downloaded newer image for mysql:5.7
|
||||
Pulling wordpress (wordpress:latest)...
|
||||
latest: Pulling from library/wordpress
|
||||
efd26ecc9548: Already exists
|
||||
a3ed95caeb02: Pull complete
|
||||
589a9d9a7c64: Pull complete
|
||||
<...>
|
||||
Digest: sha256:ed28506ae44d5def89075fd5c01456610cd6c64006addfe5210b8c675881aff6
|
||||
Status: Downloaded newer image for wordpress:latest
|
||||
Creating my_wordpress_db_1
|
||||
Creating my_wordpress_wordpress_1
|
||||
```
|
||||
|
||||
> **Note**: WordPress Multisite works only on ports `80` and/or `443`.
|
||||
If you get an error message about binding `0.0.0.0` to port `80` or `443`
|
||||
(depending on which one you specified), it is likely that the port you
|
||||
configured for WordPress is already in use by another service.
|
||||
|
||||
### Bring up WordPress in a web browser
|
||||
|
||||
At this point, WordPress should be running on port `80` of your Docker Host,
|
||||
and you can complete the "famous five-minute installation" as a WordPress
|
||||
administrator.
|
||||
|
||||
> **Note**: The WordPress site is not immediately available on port `80`
|
||||
because the containers are still being initialized and may take a couple of
|
||||
minutes before the first load.
|
||||
|
||||
If you are using Docker Desktop for Mac or Docker Desktop for Windows, you can use
|
||||
`http://localhost` as the IP address, and open `http://localhost:80` in a web
|
||||
browser.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### Shutdown and cleanup
|
||||
|
||||
The command [`docker compose down`](https://docs.docker.com/engine/reference/commandline/compose_down/) removes the
|
||||
containers and default network, but preserves your WordPress database.
|
||||
|
||||
The command `docker compose down --volumes` removes the containers, default
|
||||
network, and the WordPress database.
|
||||
|
||||
## More Compose documentation
|
||||
|
||||
* [Docker Compose overview](https://docs.docker.com/compose/)
|
||||
* [Install Docker Compose](https://docs.docker.com/compose/install/)
|
||||
* [Getting Started with Docker Compose](https://docs.docker.com/compose/gettingstarted/)
|
||||
* [Docker Compose Command line reference](https://docs.docker.com/compose/reference/)
|
||||
* [Compose file reference](https://docs.docker.com/compose/compose-file/)
|
||||
* [Awesome Compose WordPress sample](../../wordpress-mysql/README.md)
|
Binary file not shown.
After ![]() (image error) Size: 29 KiB |
Binary file not shown.
After ![]() (image error) Size: 60 KiB |
8
open_in_new.svg
Normal file
8
open_in_new.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0_1191_12637" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="24" height="24">
|
||||
<path d="M18 19H6C5.45 19 5 18.55 5 18V6C5 5.45 5.45 5 6 5H11C11.55 5 12 4.55 12 4C12 3.45 11.55 3 11 3H5C3.89 3 3 3.9 3 5V19C3 20.1 3.9 21 5 21H19C20.1 21 21 20.1 21 19V13C21 12.45 20.55 12 20 12C19.45 12 19 12.45 19 13V18C19 18.55 18.55 19 18 19ZM14 4C14 4.55 14.45 5 15 5H17.59L8.46 14.13C8.07 14.52 8.07 15.15 8.46 15.54C8.85 15.93 9.48 15.93 9.87 15.54L19 6.41V9C19 9.55 19.45 10 20 10C20.55 10 21 9.55 21 9V4C21 3.45 20.55 3 20 3H15C14.45 3 14 3.45 14 4Z" fill="black"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_1191_12637)">
|
||||
<rect width="24" height="24" fill="#086DD7"/>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 788 B |
|
@ -39,7 +39,7 @@ Before deploying this setup, you need to configure the following values in the [
|
|||
- PIHOLE_PW (admin password)
|
||||
- PIHOLE_ROUTER_IP (only needed for activated conditional forwarding)
|
||||
- PIHOLE_NETWORK_DOMAIN (only needed for activated conditional forwarding)
|
||||
- PIHOLE_HOST_IP (IPv4 address of your Pi-hole - needs to by static)
|
||||
- PIHOLE_HOST_IP (IPv4 address of your Pi-hole - needs to be static)
|
||||
- PIHOLE_HOST_IPV6 (IPv6 address of your Pi-hole - can be empty if you only use IPv4)
|
||||
|
||||
### Conditional forwarding (optional, default: enabled)
|
||||
|
@ -101,7 +101,7 @@ $ docker compose down -v
|
|||
```
|
||||
If you created an empty file, you may also check the ownership to prevent permission problems.
|
||||
|
||||
### - Installing on Ubuntu may conflict with `systemd-resolved` - see [Installing on Ubuntu](https://github.com/pi-hole/docker-pi-hole#installing-on-ubuntu) for help.
|
||||
### - Installing on Ubuntu may conflict with `systemd-resolved` - see [Installing on Ubuntu](https://github.com/pi-hole/docker-pi-hole#installing-on-ubuntu-or-fedora) for help.
|
||||
|
||||
### - Environment variables are version-dependent
|
||||
Environment variables like "CONDIIONAL_FORWARDING*" and "DNS1" are deprecated and replaced by e.g. "REV_SERVER*" and "PIHOLE_DNS" in version 5.8+.
|
||||
|
|
|
@ -5,7 +5,7 @@ services:
|
|||
environment:
|
||||
- POSTGRES_USER=${POSTGRES_USER}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PW}
|
||||
- POSTGRES_DB=${POSTGRES_DB} #optional (specify default database instead of $POSTGRES_USER)
|
||||
- POSTGRES_DB=${POSTGRES_DB} #optional (specify default database instead of $POSTGRES_DB)
|
||||
ports:
|
||||
- "5432:5432"
|
||||
restart: always
|
||||
|
|
|
@ -29,7 +29,6 @@ services:
|
|||
expose:
|
||||
- 3000
|
||||
mongo:
|
||||
container_name: mongo
|
||||
restart: always
|
||||
image: mongo:4.2.0
|
||||
volumes:
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/react-express-mongodb)
|
||||
|
||||
### React application with a NodeJS backend and a MongoDB database
|
||||
|
||||
Project structure:
|
||||
|
@ -132,14 +139,3 @@ __Explanation of service mongo__
|
|||
:key: `If you wish to check your DB changes on your local machine as well. You should have installed MongoDB locally, otherwise you can't access your mongodb service of container from host machine.`
|
||||
|
||||
:white_check_mark: You should check your __mongo__ version is same as used in image. You can see the version of __mongo__ image in `docker-compose `file, I used __image: mongo:4.2.0__. If your mongo db version on your machine is not same then furst you have to updated your local __mongo__ version in order to works correctly.
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/react-express-mongodb
|
||||
```
|
||||
|
|
|
@ -9,7 +9,6 @@ services:
|
|||
volumes:
|
||||
- ./frontend:/usr/src/app
|
||||
- /usr/src/app/node_modules
|
||||
container_name: frontend
|
||||
restart: always
|
||||
networks:
|
||||
- react-express
|
||||
|
@ -17,7 +16,6 @@ services:
|
|||
- backend
|
||||
|
||||
backend:
|
||||
container_name: backend
|
||||
restart: always
|
||||
build:
|
||||
context: backend
|
||||
|
@ -33,11 +31,10 @@ services:
|
|||
expose:
|
||||
- 3000
|
||||
mongo:
|
||||
container_name: mongo
|
||||
restart: always
|
||||
image: mongo:4.2.0
|
||||
volumes:
|
||||
- ./data:/data/db
|
||||
- mongo_data:/data/db
|
||||
networks:
|
||||
- express-mongo
|
||||
expose:
|
||||
|
@ -45,3 +42,6 @@ services:
|
|||
networks:
|
||||
react-express:
|
||||
express-mongo:
|
||||
|
||||
volumes:
|
||||
mongo_data:
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/react-express-mysql)
|
||||
|
||||
### React application with a NodeJS backend and a MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -97,14 +104,3 @@ Removing react-express-mysql_db_1 ... done
|
|||
Removing network react-express-mysql_default
|
||||
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/react-express-mysql
|
||||
```
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/react-java-mysql)
|
||||
|
||||
### React application with a Spring backend and a MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -35,27 +42,27 @@ services:
|
|||
...
|
||||
```
|
||||
The compose file defines an application with three services `frontend`, `backend` and `db`.
|
||||
When deploying the application, docker compose maps port 3000 of the frontend service container to port 3000 of the host as specified in the file.
|
||||
When deploying the application, docker compose maps port 3000 of the frontend service container to port 3000 of the host as specified in the file.
|
||||
Make sure port 3000 on the host is not already being in use.
|
||||
|
||||
> ℹ️ **_INFO_**
|
||||
> For compatibility purpose between `AMD64` and `ARM64` architecture, we use a MariaDB as database instead of MySQL.
|
||||
> You still can use the MySQL image by uncommenting the following line in the Compose file
|
||||
> ℹ️ **_INFO_**
|
||||
> For compatibility purpose between `AMD64` and `ARM64` architecture, we use a MariaDB as database instead of MySQL.
|
||||
> You still can use the MySQL image by uncommenting the following line in the Compose file
|
||||
> `#image: mysql:8.0.27`
|
||||
|
||||
## Deploy with docker compose
|
||||
|
||||
```
|
||||
$ docker compose up -d
|
||||
Creating network "react-java-mysql_default" with the default driver
|
||||
Creating network "react-java-mysql-default" with the default driver
|
||||
Building backend
|
||||
Step 1/17 : FROM maven:3.6.3-jdk-11 AS builder
|
||||
...
|
||||
Successfully tagged react-java-mysql_frontend:latest
|
||||
WARNING: Image for service frontend was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
|
||||
Creating react-java-mysql_frontend_1 ... done
|
||||
Creating react-java-mysql_db_1 ... done
|
||||
Creating react-java-mysql_backend_1 ... done
|
||||
Creating react-java-mysql-frontend-1 ... done
|
||||
Creating react-java-mysql-db-1 ... done
|
||||
Creating react-java-mysql-backend-1 ... done
|
||||
```
|
||||
|
||||
## Expected result
|
||||
|
@ -64,9 +71,9 @@ Listing containers must show three containers running and the port mapping as be
|
|||
```
|
||||
$ docker ps
|
||||
ONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
a63dee74d79e react-java-mysql_backend "java -Djava.securit…" 39 seconds ago Up 37 seconds react-java-mysql_backend_1
|
||||
6a7364c0812e react-java-mysql_frontend "docker-entrypoint.s…" 39 seconds ago Up 33 seconds 0.0.0.0:3000->3000/tcp react-java-mysql_frontend_1
|
||||
b176b18fbec4 mysql:8.0.19 "docker-entrypoint.s…" 39 seconds ago Up 37 seconds 3306/tcp, 33060/tcp react-java-mysql_db_1
|
||||
a63dee74d79e react-java-mysql-backend "java -Djava.securit…" 39 seconds ago Up 37 seconds react-java-mysql_backend-1
|
||||
6a7364c0812e react-java-mysql-frontend "docker-entrypoint.s…" 39 seconds ago Up 33 seconds 0.0.0.0:3000->3000/tcp react-java-mysql_frontend-1
|
||||
b176b18fbec4 mysql:8.0.19 "docker-entrypoint.s…" 39 seconds ago Up 37 seconds 3306/tcp, 33060/tcp react-java-mysql_db-1
|
||||
```
|
||||
|
||||
After the application starts, navigate to `http://localhost:3000` in your web browser to get a colorful message.
|
||||
|
@ -75,19 +82,11 @@ After the application starts, navigate to `http://localhost:3000` in your web br
|
|||
Stop and remove the containers
|
||||
```
|
||||
$ docker compose down
|
||||
Stopping react-java-mysql_backend_1 ... done
|
||||
Stopping react-java-mysql_frontend_1 ... done
|
||||
Stopping react-java-mysql_db_1 ... done
|
||||
Removing react-java-mysql_backend_1 ... done
|
||||
Removing react-java-mysql_frontend_1 ... done
|
||||
Removing react-java-mysql_db_1 ... done
|
||||
Removing network react-java-mysql_default
|
||||
Stopping react-java-mysql-backend-1 ... done
|
||||
Stopping react-java-mysql-frontend-1 ... done
|
||||
Stopping react-java-mysql-db-1 ... done
|
||||
Removing react-java-mysql-backend-1 ... done
|
||||
Removing react-java-mysql-frontend-1 ... done
|
||||
Removing react-java-mysql-db-1 ... done
|
||||
Removing network react-java-mysql-default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly frontend or the backend services inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/react-java-mysql`
|
||||
|
||||

|
|
@ -1,5 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/react-nginx)
|
||||
|
||||
### An project deploy React Application with Nginx
|
||||
|
||||
Project structure:
|
||||
|
@ -86,14 +92,3 @@ Stopping frontend ... done
|
|||
Removing frontend ... done
|
||||
Removing network react-nginx_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
|
||||

|
||||
|
||||
To develop directly on the services inside containers, use the HTTPS Git url of the sample:
|
||||
```
|
||||
https://github.com/docker/awesome-compose/tree/master/react-nginx
|
||||
```
|
|
@ -1,5 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/react-rust-postgres)
|
||||
|
||||
### React application with a Rust backend and a Postgresql database
|
||||
|
||||
Project structure:
|
||||
|
@ -74,11 +80,3 @@ Removing react-rust-postgres_frontend_1 ... done
|
|||
Removing react-rust-postgres_db_1 ... done
|
||||
Removing network react-rust-postgres_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly frontend or the backend services inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/react-rust-postgres`
|
||||
|
||||

|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/sparkjava-mysql)
|
||||
|
||||
### Java Spark application with MySQL database
|
||||
|
||||
Project structure:
|
||||
|
@ -75,11 +82,3 @@ Removing sparkjava-mysql_backend_1 ... done
|
|||
Removing sparkjava-mysql_db_1 ... done
|
||||
Removing network sparkjava-mysql_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly frontend or the backend services inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/sparkjava-mysql`
|
||||
|
||||

|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/sparkjava)
|
||||
|
||||
### Spark Java
|
||||
|
||||
Project structure:
|
||||
|
@ -59,11 +66,3 @@ Stopping sparkjava_sparkjava_1 ... done
|
|||
Removing sparkjava_sparkjava_1 ... done
|
||||
Removing network sparkjava_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly sparkjava service inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/sparkjava`
|
||||
|
||||

|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/spring-postgres)
|
||||
|
||||
### Java application with Spring framework and a Postgres database
|
||||
|
||||
Project structure:
|
||||
|
@ -77,11 +84,3 @@ Removing spring-postgres_db_1 ... done
|
|||
Removing spring-postgres_backend_1 ... done
|
||||
Removing network spring-postgres_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly frontend or the backend services inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/spring-postgres`
|
||||
|
||||

|
||||
|
|
|
@ -33,7 +33,7 @@ FROM eclipse-temurin:17-jre-focal
|
|||
EXPOSE 8080
|
||||
VOLUME /tmp
|
||||
ARG DEPENDENCY=/workdir/server/target/dependency
|
||||
COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib
|
||||
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
|
||||
COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app
|
||||
ENTRYPOINT ["java","-cp","app:app/lib/*","com.company.project.Application"]
|
||||
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/lib /app/lib
|
||||
COPY --from=prepare-production ${DEPENDENCY}/META-INF /app/META-INF
|
||||
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/classes /app
|
||||
ENTRYPOINT ["java","-cp","app:app/lib/*","com.company.project.Application"]
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/traefik-golang)
|
||||
|
||||
### TRAEFIK proxy with GO backend
|
||||
|
||||
Project structure:
|
||||
|
@ -92,11 +99,3 @@ Stop and remove the containers
|
|||
```
|
||||
$ docker compose down
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly the backend service inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/traefik-golang`
|
||||
|
||||

|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
## Compose sample application
|
||||
|
||||
### Use with Docker Development Environments
|
||||
|
||||
You can open this sample in the Dev Environments feature of Docker Desktop version 4.12 or later.
|
||||
|
||||
[Open in Docker Dev Environments <img src="../open_in_new.svg" alt="Open in Docker Dev Environments" align="top"/>](https://open.docker.com/dashboard/dev-envs?url=https://github.com/docker/awesome-compose/tree/master/vuejs)
|
||||
|
||||
### VueJS
|
||||
|
||||
Project structure:
|
||||
|
@ -59,11 +66,3 @@ Stopping vuejs_web_1 ... done
|
|||
Removing vuejs_web_1 ... done
|
||||
Removing network vuejs_default
|
||||
```
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You can use this sample with the Dev Environments feature of Docker Desktop.
|
||||
To develop directly web service inside containers, you just need to use the https git url of the sample:
|
||||
`https://github.com/docker/awesome-compose/tree/master/vuejs`
|
||||
|
||||

|
||||
|
|
36
wasmedge-kafka-mysql/.docker/docker-compose.yml
Normal file
36
wasmedge-kafka-mysql/.docker/docker-compose.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
services:
|
||||
redpanda:
|
||||
image: docker.redpanda.com/vectorized/redpanda:v22.2.2
|
||||
command:
|
||||
- redpanda start
|
||||
- --smp 1
|
||||
- --overprovisioned
|
||||
- --node-id 0
|
||||
- --kafka-addr PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092
|
||||
- --advertise-kafka-addr PLAINTEXT://redpanda:29092,OUTSIDE://redpanda:9092
|
||||
- --pandaproxy-addr 0.0.0.0:8082
|
||||
- --advertise-pandaproxy-addr localhost:8082
|
||||
ports:
|
||||
- 8081:8081
|
||||
- 8082:8082
|
||||
- 9092:9092
|
||||
- 9644:9644
|
||||
- 29092:29092
|
||||
volumes:
|
||||
- ./kafka:/app
|
||||
etl:
|
||||
image: etl-kafka
|
||||
platform: wasi/wasm
|
||||
build:
|
||||
context: etl
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
KAFKA_URL: kafka://redpanda:9092/order
|
||||
RUST_BACKTRACE: full
|
||||
RUST_LOG: info
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
117
wasmedge-kafka-mysql/README.md
Normal file
117
wasmedge-kafka-mysql/README.md
Normal file
|
@ -0,0 +1,117 @@
|
|||
# Compose sample application
|
||||
|
||||

|
||||
|
||||
This sample demonstrates a WebAssembly (Wasm) microservice written in Rust. It subscribes to a Kafka queue topic on a Redpanda server, and then transforms and saves each message into a MySQL (MariaDB) database table. The microservice is compiled into Wasm and runs in the WasmEdge runtime, which is a secure and lightweight alternative to natively compiled Rust apps in Linux containers.
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You will need a version of Docker Desktop or Docker CLI with Wasm support.
|
||||
|
||||
* [Install Docker Desktop + Wasm (Beta)](https://docs.docker.com/desktop/wasm/)
|
||||
* [Install Docker CLI + Wasm](https://github.com/chris-crone/wasm-day-na-22/tree/main/server)
|
||||
|
||||
## WasmEdge server with Redpanda and MySQL database
|
||||
|
||||
Project structure:
|
||||
|
||||
```
|
||||
.
|
||||
+-- compose.yml
|
||||
|-- etl
|
||||
|-- Dockerfile
|
||||
|-- Cargo.toml
|
||||
+-- src
|
||||
|-- main.rs
|
||||
|-- kafka
|
||||
|-- order.json
|
||||
|-- db
|
||||
|-- db-password.txt
|
||||
```
|
||||
|
||||
The [compose.yml](compose.yml) is as follows.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
redpanda:
|
||||
image: docker.redpanda.com/vectorized/redpanda:v22.2.2
|
||||
command:
|
||||
- redpanda start
|
||||
- --smp 1
|
||||
- --overprovisioned
|
||||
- --node-id 0
|
||||
- --kafka-addr PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092
|
||||
- --advertise-kafka-addr PLAINTEXT://redpanda:29092,OUTSIDE://redpanda:9092
|
||||
- --pandaproxy-addr 0.0.0.0:8082
|
||||
- --advertise-pandaproxy-addr localhost:8082
|
||||
ports:
|
||||
- 8081:8081
|
||||
- 8082:8082
|
||||
- 9092:9092
|
||||
- 9644:9644
|
||||
- 29092:29092
|
||||
volumes:
|
||||
- ./kafka:/app
|
||||
|
||||
etl:
|
||||
image: etl-kafka
|
||||
build:
|
||||
context: etl
|
||||
platforms:
|
||||
- wasi/wasm32
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
KAFKA_URL: kafka://redpanda:9092/order
|
||||
RUST_BACKTRACE: full
|
||||
RUST_LOG: info
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
||||
```
|
||||
|
||||
The compose file defines an application with three services `redpanda`, `etl` and `db`. The `redpanda` service is a Kafka-compatible messaging server that produces messages in a queue topic. The `etl` service, in the WasmEdge container that subscribes to the queue topic and receives incoming messages. Each incoming message is parsed and stored in the `db` MySQL (MariaDB) database server.
|
||||
|
||||
## Deploy with docker compose
|
||||
|
||||
```bash
|
||||
$ docker compose up -d
|
||||
...
|
||||
⠿ Network wasmedge-kafka-mysql_default Created 0.1s
|
||||
⠿ Container wasmedge-kafka-mysql-redpanda-1 Created 0.3s
|
||||
⠿ Container wasmedge-kafka-mysql-etl-1 Created 0.3s
|
||||
⠿ Container wasmedge-kafka-mysql-db-1 Created 0.3s
|
||||
```
|
||||
|
||||
## Expected result
|
||||
|
||||
```bash
|
||||
$ docker compose ps
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
wasmedge-kafka-mysql-db-1 "docker-entrypoint.s…" db running 3306/tcp
|
||||
wasmedge-kafka-mysql-etl-1 "kafka.wasm" etl running
|
||||
wasmedge-kafka-mysql-redpanda-1 "/entrypoint.sh 'red…" redpanda running 0.0.0.0:8081-8082->8081-8082/tcp, :::8081-8082->8081-8082/tcp, 0.0.0.0:9092->9092/tcp, :::9092->9092/tcp, 0.0.0.0:9644->9644/tcp, :::9644->9644/tcp, 0.0.0.0:29092->29092/tcp, :::29092->29092/tcp
|
||||
```
|
||||
|
||||
After the application starts,
|
||||
log into the Redpanda container and send a message to the queue topic `order` as follows.
|
||||
|
||||
```bash
|
||||
$ docker compose exec redpanda /bin/bash
|
||||
redpanda@1add2615774b:/$ cd /app
|
||||
redpanda@1add2615774b:/app$ cat order.json | rpk topic produce order
|
||||
Produced to partition 0 at offset 0 with timestamp 1667922788523.
|
||||
```
|
||||
|
||||
To see the data in the database container, you can use the following commands.
|
||||
|
||||
```bash
|
||||
$ docker compose exec db /bin/bash
|
||||
root@c97c472db02e:/# mysql -u root -pwhalehello mysql
|
||||
mysql> select * from orders;
|
||||
... ...
|
||||
```
|
||||
|
36
wasmedge-kafka-mysql/compose.yml
Normal file
36
wasmedge-kafka-mysql/compose.yml
Normal file
|
@ -0,0 +1,36 @@
|
|||
services:
|
||||
redpanda:
|
||||
image: docker.redpanda.com/vectorized/redpanda:v22.2.2
|
||||
command:
|
||||
- redpanda start
|
||||
- --smp 1
|
||||
- --overprovisioned
|
||||
- --node-id 0
|
||||
- --kafka-addr PLAINTEXT://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092
|
||||
- --advertise-kafka-addr PLAINTEXT://redpanda:29092,OUTSIDE://redpanda:9092
|
||||
- --pandaproxy-addr 0.0.0.0:8082
|
||||
- --advertise-pandaproxy-addr localhost:8082
|
||||
ports:
|
||||
- 8081:8081
|
||||
- 8082:8082
|
||||
- 9092:9092
|
||||
- 9644:9644
|
||||
- 29092:29092
|
||||
volumes:
|
||||
- ./kafka:/app
|
||||
etl:
|
||||
image: etl-kafka
|
||||
platform: wasi/wasm
|
||||
build:
|
||||
context: etl
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
KAFKA_URL: kafka://redpanda:9092/order
|
||||
RUST_BACKTRACE: full
|
||||
RUST_LOG: info
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
1
wasmedge-kafka-mysql/db/db-password.txt
Normal file
1
wasmedge-kafka-mysql/db/db-password.txt
Normal file
|
@ -0,0 +1 @@
|
|||
whalehello
|
17
wasmedge-kafka-mysql/etl/Cargo.toml
Normal file
17
wasmedge-kafka-mysql/etl/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "kafka"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.65"
|
||||
mega_etl = {git = "https://github.com/second-state/MEGA.git"}
|
||||
tokio_wasi = {version = '1.21', features = ["rt", "macros"]}
|
||||
env_logger = "0.9"
|
||||
log = "0.4"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
http_req_wasi = "0.10"
|
||||
lazy_static = "1.4.0"
|
27
wasmedge-kafka-mysql/etl/Dockerfile
Normal file
27
wasmedge-kafka-mysql/etl/Dockerfile
Normal file
|
@ -0,0 +1,27 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM --platform=$BUILDPLATFORM rust:1.64 AS buildbase
|
||||
RUN <<EOT bash
|
||||
set -ex
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
git \
|
||||
clang
|
||||
rustup target add wasm32-wasi
|
||||
EOT
|
||||
# This line installs WasmEdge including the AOT compiler
|
||||
RUN curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash
|
||||
|
||||
FROM buildbase AS build
|
||||
COPY Cargo.toml .
|
||||
COPY src ./src
|
||||
# Build the Wasm binary
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/git/db \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/cache \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/index \
|
||||
cargo build --target wasm32-wasi --release
|
||||
# This line builds the AOT Wasm binary
|
||||
RUN /root/.wasmedge/bin/wasmedgec target/wasm32-wasi/release/kafka.wasm kafka.wasm
|
||||
|
||||
FROM scratch
|
||||
ENTRYPOINT [ "kafka.wasm" ]
|
||||
COPY --link --from=build /kafka.wasm /kafka.wasm
|
58
wasmedge-kafka-mysql/etl/src/main.rs
Normal file
58
wasmedge-kafka-mysql/etl/src/main.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use mega_etl::{async_trait, Pipe, Transformer, TransformerError, TransformerResult};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Order {
|
||||
order_id: i32,
|
||||
product_id: i32,
|
||||
quantity: i32,
|
||||
amount: f32,
|
||||
shipping: f32,
|
||||
tax: f32,
|
||||
shipping_address: String,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Transformer for Order {
|
||||
async fn transform(inbound_data: &Vec<u8>) -> TransformerResult<Vec<String>> {
|
||||
let s = std::str::from_utf8(&inbound_data)
|
||||
.map_err(|e| TransformerError::Custom(e.to_string()))?;
|
||||
let order: Order = serde_json::from_str(String::from(s).as_str())
|
||||
.map_err(|e| TransformerError::Custom(e.to_string()))?;
|
||||
log::info!("{:?}", &order);
|
||||
let mut ret = vec![];
|
||||
let sql_string = format!(
|
||||
r"INSERT INTO orders VALUES ({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, CURRENT_TIMESTAMP);",
|
||||
order.order_id,
|
||||
order.product_id,
|
||||
order.quantity,
|
||||
order.amount,
|
||||
order.shipping,
|
||||
order.tax,
|
||||
order.shipping_address,
|
||||
);
|
||||
dbg!(sql_string.clone());
|
||||
ret.push(sql_string);
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
async fn init() -> TransformerResult<String> {
|
||||
Ok(String::from(
|
||||
r"CREATE TABLE IF NOT EXISTS orders (order_id INT, product_id INT, quantity INT, amount FLOAT, shipping FLOAT, tax FLOAT, shipping_address VARCHAR(50), date_registered TIMESTAMP DEFAULT CURRENT_TIMESTAMP);",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
// can use builder later
|
||||
let database_uri = std::env::var("DATABASE_URL")?;
|
||||
let kafka_uri = std::env::var("KAFKA_URL")?;
|
||||
let mut pipe = Pipe::new(database_uri, kafka_uri).await;
|
||||
|
||||
// This is async because this calls the async transform() function in Order
|
||||
pipe.start::<Order>().await?;
|
||||
Ok(())
|
||||
}
|
1
wasmedge-kafka-mysql/kafka/order.json
Normal file
1
wasmedge-kafka-mysql/kafka/order.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"order_id": 1,"product_id": 12,"quantity": 2,"amount": 56.0,"shipping": 15.0,"tax": 2.0,"shipping_address": "Mataderos 2312"}
|
25
wasmedge-mysql-nginx/.docker/docker-compose.yml
Normal file
25
wasmedge-mysql-nginx/.docker/docker-compose.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
services:
|
||||
frontend:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- 8090:80
|
||||
volumes:
|
||||
- ./frontend:/usr/share/nginx/html
|
||||
|
||||
backend:
|
||||
image: demo-microservice
|
||||
platform: wasi/wasm
|
||||
build:
|
||||
context: backend/
|
||||
ports:
|
||||
- 8080:8080
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
RUST_BACKTRACE: full
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
125
wasmedge-mysql-nginx/README.md
Normal file
125
wasmedge-mysql-nginx/README.md
Normal file
|
@ -0,0 +1,125 @@
|
|||
# Compose sample application
|
||||
|
||||

|
||||
|
||||
This sample demonstrates a web application with a WebAssembly (Wasm) microservice, written in Rust. The Wasm microservice is an HTTP API connected to a MySQL (MariaDB) database. The API is invoked via from JavaScript in a web interface serving static HTML. The microservice is compiled into WebAssembly (Wasm) and runs in the WasmEdge Runtime, a secure and lightweight alternative to natively compiled Rust apps in Linux containers. Checkout [this article](https://blog.logrocket.com/rust-microservices-server-side-webassembly/) or [this video](https://www.youtube.com/watch?v=VSqMPFr7SEs) to learn how the Rust code in this microservice works.
|
||||
|
||||
## Use with Docker Development Environments
|
||||
|
||||
You will need a version of Docker Desktop or Docker CLI with Wasm support.
|
||||
|
||||
* [Install Docker Desktop + Wasm (Beta)](https://docs.docker.com/desktop/wasm/)
|
||||
* [Install Docker CLI + Wasm](https://github.com/chris-crone/wasm-day-na-22/tree/main/server)
|
||||
|
||||
## WasmEdge server with Nginx proxy and MySQL database
|
||||
|
||||
Project structure:
|
||||
|
||||
```
|
||||
.
|
||||
+-- compose.yml
|
||||
|-- backend
|
||||
+-- Dockerfile
|
||||
|-- Cargo.toml
|
||||
|-- src
|
||||
+-- main.rs
|
||||
|-- frontend
|
||||
+-- index.html
|
||||
|-- js
|
||||
+-- app.js
|
||||
|-- db
|
||||
+-- orders.json
|
||||
|-- update_order.json
|
||||
```
|
||||
|
||||
The [compose.yml](compose.yml) file:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
frontend:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- 8090:80
|
||||
volumes:
|
||||
- ./frontend:/usr/share/nginx/html
|
||||
|
||||
backend:
|
||||
image: demo-microservice
|
||||
build:
|
||||
context: backend/
|
||||
platforms:
|
||||
- wasi/wasm32
|
||||
ports:
|
||||
- 8080:8080
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
RUST_BACKTRACE: full
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
||||
```
|
||||
|
||||
The compose file defines an application with three services `frontend`, `backend` and `db`. The `frontend` is a simple Nginx server that hosts static web pages that access the `backend` web service, in the WasmEdge container, via HTTP port 8080. When deploying the application, docker compose maps port 8090 of the `frontend` service container to port 8090 of the host as specified in the file. Make sure that ports 8090 and 8080 on the host are not already being used.
|
||||
|
||||
## Deploy with docker compose
|
||||
|
||||
```bash
|
||||
$ docker compose up -d
|
||||
...
|
||||
⠿ Network wasmedge-mysql-nginx_default Created
|
||||
⠿ Container wasmedge-mysql-nginx-db-1 Created
|
||||
⠿ Container wasmedge-mysql-nginx-frontend-1 Created
|
||||
⠿ Container wasmedge-mysql-nginx-backend-1 Created
|
||||
```
|
||||
|
||||
## Expected result
|
||||
|
||||
```bash
|
||||
$ docker compose ps
|
||||
NAME COMMAND SERVICE STATUS PORTS
|
||||
wasmedge-mysql-nginx-backend-1 "order_demo_service.…" backend running 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
|
||||
wasmedge-mysql-nginx-db-1 "docker-entrypoint.s…" db running 3306/tcp
|
||||
wasmedge-mysql-nginx-frontend-1 "/docker-entrypoint.…" frontend running 0.0.0.0:8090->80/tcp, :::8090->80/tcp
|
||||
```
|
||||
|
||||
After the application starts, go to `http://localhost:8090` in your web browser to display the web frontend.
|
||||
|
||||
### Using the API with `curl`
|
||||
|
||||
As an alternative to the web frontend, you can use `curl` to interact with the WasmEdge API directly (the `backend` service).
|
||||
|
||||
When the WasmEdge web service receives a GET request to the `/init` endpoint, it would initialize the database with the `orders` table.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/init
|
||||
```
|
||||
|
||||
When the WasmEdge web service receives a POST request to the `/create_order` endpoint, it extracts the JSON data from the POST body and inserts an `Order` record into the database table.
|
||||
To insert multiple records, use the `/create_orders` endpoint and POST a JSON array of `Order` objects:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/create_orders -X POST -d @db/orders.json
|
||||
```
|
||||
|
||||
When the WasmEdge web service receives a GET request to the `/orders` endpoint, it gets all rows from the `orders` table and return the result set in a JSON array in the HTTP response.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/orders
|
||||
```
|
||||
|
||||
When the WasmEdge web service receives a POST request to the `/update_order` endpoint, it extracts the JSON data from the POST body and update the `Order` record in the database table that matches the `order_id` in the input data.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/update_order -X POST -d @db/update_order.json
|
||||
```
|
||||
|
||||
When the WasmEdge web service receives a GET request to the `/delete_order` endpoint, it deletes the row in the `orders` table that matches the `id` GET parameter.
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/delete_order?id=2
|
||||
```
|
||||
|
13
wasmedge-mysql-nginx/backend/Cargo.toml
Normal file
13
wasmedge-mysql-nginx/backend/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "order_demo_service"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
url = "2.3"
|
||||
mysql_async_wasi = "0.30"
|
||||
hyper_wasi = { version = "0.15", features = ["full"] }
|
||||
tokio_wasi = { version = "1", features = ["io-util", "fs", "net", "time", "rt", "macros"] }
|
29
wasmedge-mysql-nginx/backend/Dockerfile
Normal file
29
wasmedge-mysql-nginx/backend/Dockerfile
Normal file
|
@ -0,0 +1,29 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM --platform=$BUILDPLATFORM rust:1.64 AS buildbase
|
||||
WORKDIR /src
|
||||
RUN <<EOT bash
|
||||
set -ex
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
git \
|
||||
clang
|
||||
rustup target add wasm32-wasi
|
||||
EOT
|
||||
# This line installs WasmEdge including the AOT compiler
|
||||
RUN curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash
|
||||
|
||||
FROM buildbase AS build
|
||||
COPY Cargo.toml .
|
||||
COPY src ./src
|
||||
# Build the Wasm binary
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/git/db \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/cache \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/index \
|
||||
cargo build --target wasm32-wasi --release
|
||||
# This line builds the AOT Wasm binary
|
||||
RUN /root/.wasmedge/bin/wasmedgec target/wasm32-wasi/release/order_demo_service.wasm order_demo_service.wasm
|
||||
|
||||
FROM scratch
|
||||
ENTRYPOINT [ "order_demo_service.wasm" ]
|
||||
COPY --link --from=build /src/order_demo_service.wasm /order_demo_service.wasm
|
237
wasmedge-mysql-nginx/backend/src/main.rs
Normal file
237
wasmedge-mysql-nginx/backend/src/main.rs
Normal file
|
@ -0,0 +1,237 @@
|
|||
use hyper::service::{make_service_fn, service_fn};
|
||||
use hyper::{Body, Method, Request, Response, StatusCode, Server};
|
||||
pub use mysql_async::prelude::*;
|
||||
pub use mysql_async::*;
|
||||
use std::convert::Infallible;
|
||||
use std::net::SocketAddr;
|
||||
use std::result::Result;
|
||||
use std::collections::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
fn get_url() -> String {
|
||||
if let Ok(url) = std::env::var("DATABASE_URL") {
|
||||
let opts = Opts::from_url(&url).expect("DATABASE_URL invalid");
|
||||
if opts
|
||||
.db_name()
|
||||
.expect("a database name is required")
|
||||
.is_empty()
|
||||
{
|
||||
panic!("database name is empty");
|
||||
}
|
||||
url
|
||||
} else {
|
||||
"mysql://root:pass@127.0.0.1:3306/mysql".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Order {
|
||||
order_id: i32,
|
||||
product_id: i32,
|
||||
quantity: i32,
|
||||
amount: f32,
|
||||
shipping: f32,
|
||||
tax: f32,
|
||||
shipping_address: String,
|
||||
}
|
||||
|
||||
impl Order {
|
||||
fn new(
|
||||
order_id: i32,
|
||||
product_id: i32,
|
||||
quantity: i32,
|
||||
amount: f32,
|
||||
shipping: f32,
|
||||
tax: f32,
|
||||
shipping_address: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
order_id,
|
||||
product_id,
|
||||
quantity,
|
||||
amount,
|
||||
shipping,
|
||||
tax,
|
||||
shipping_address,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_request(req: Request<Body>, pool: Pool) -> Result<Response<Body>, anyhow::Error> {
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::GET, "/") => Ok(Response::new(Body::from(
|
||||
"The valid endpoints are /init /create_order /create_orders /update_order /orders /delete_order",
|
||||
))),
|
||||
|
||||
// Simply echo the body back to the client.
|
||||
(&Method::POST, "/echo") => Ok(Response::new(req.into_body())),
|
||||
|
||||
// CORS OPTIONS
|
||||
(&Method::OPTIONS, "/init") => Ok(response_build(&String::from(""))),
|
||||
(&Method::OPTIONS, "/create_order") => Ok(response_build(&String::from(""))),
|
||||
(&Method::OPTIONS, "/create_orders") => Ok(response_build(&String::from(""))),
|
||||
(&Method::OPTIONS, "/update_order") => Ok(response_build(&String::from(""))),
|
||||
(&Method::OPTIONS, "/delete_order") => Ok(response_build(&String::from(""))),
|
||||
(&Method::OPTIONS, "/orders") => Ok(response_build(&String::from(""))),
|
||||
|
||||
(&Method::GET, "/init") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
"DROP TABLE IF EXISTS orders;".ignore(&mut conn).await?;
|
||||
"CREATE TABLE orders (order_id INT, product_id INT, quantity INT, amount FLOAT, shipping FLOAT, tax FLOAT, shipping_address VARCHAR(20));".ignore(&mut conn).await?;
|
||||
drop(conn);
|
||||
Ok(response_build("{\"status\":true}"))
|
||||
}
|
||||
|
||||
(&Method::POST, "/create_order") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
|
||||
let byte_stream = hyper::body::to_bytes(req).await?;
|
||||
let order: Order = serde_json::from_slice(&byte_stream).unwrap();
|
||||
|
||||
"INSERT INTO orders (order_id, product_id, quantity, amount, shipping, tax, shipping_address) VALUES (:order_id, :product_id, :quantity, :amount, :shipping, :tax, :shipping_address)"
|
||||
.with(params! {
|
||||
"order_id" => order.order_id,
|
||||
"product_id" => order.product_id,
|
||||
"quantity" => order.quantity,
|
||||
"amount" => order.amount,
|
||||
"shipping" => order.shipping,
|
||||
"tax" => order.tax,
|
||||
"shipping_address" => &order.shipping_address,
|
||||
})
|
||||
.ignore(&mut conn)
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
Ok(response_build("{\"status\":true}"))
|
||||
}
|
||||
|
||||
(&Method::POST, "/create_orders") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
|
||||
let byte_stream = hyper::body::to_bytes(req).await?;
|
||||
let orders: Vec<Order> = serde_json::from_slice(&byte_stream).unwrap();
|
||||
|
||||
"INSERT INTO orders (order_id, product_id, quantity, amount, shipping, tax, shipping_address) VALUES (:order_id, :product_id, :quantity, :amount, :shipping, :tax, :shipping_address)"
|
||||
.with(orders.iter().map(|order| {
|
||||
params! {
|
||||
"order_id" => order.order_id,
|
||||
"product_id" => order.product_id,
|
||||
"quantity" => order.quantity,
|
||||
"amount" => order.amount,
|
||||
"shipping" => order.shipping,
|
||||
"tax" => order.tax,
|
||||
"shipping_address" => &order.shipping_address,
|
||||
}
|
||||
}))
|
||||
.batch(&mut conn)
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
Ok(response_build("{\"status\":true}"))
|
||||
}
|
||||
|
||||
(&Method::POST, "/update_order") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
|
||||
let byte_stream = hyper::body::to_bytes(req).await?;
|
||||
let order: Order = serde_json::from_slice(&byte_stream).unwrap();
|
||||
|
||||
"UPDATE orders SET product_id=:product_id, quantity=:quantity, amount=:amount, shipping=:shipping, tax=:tax, shipping_address=:shipping_address WHERE order_id=:order_id"
|
||||
.with(params! {
|
||||
"product_id" => order.product_id,
|
||||
"quantity" => order.quantity,
|
||||
"amount" => order.amount,
|
||||
"shipping" => order.shipping,
|
||||
"tax" => order.tax,
|
||||
"shipping_address" => &order.shipping_address,
|
||||
"order_id" => order.order_id,
|
||||
})
|
||||
.ignore(&mut conn)
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
Ok(response_build("{\"status\":true}"))
|
||||
}
|
||||
|
||||
(&Method::GET, "/orders") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
|
||||
let orders = "SELECT * FROM orders"
|
||||
.with(())
|
||||
.map(&mut conn, |(order_id, product_id, quantity, amount, shipping, tax, shipping_address)| {
|
||||
Order::new(
|
||||
order_id,
|
||||
product_id,
|
||||
quantity,
|
||||
amount,
|
||||
shipping,
|
||||
tax,
|
||||
shipping_address,
|
||||
)},
|
||||
).await?;
|
||||
|
||||
drop(conn);
|
||||
Ok(response_build(serde_json::to_string(&orders)?.as_str()))
|
||||
}
|
||||
|
||||
(&Method::GET, "/delete_order") => {
|
||||
let mut conn = pool.get_conn().await.unwrap();
|
||||
|
||||
let params: HashMap<String, String> = req.uri().query().map(|v| {
|
||||
url::form_urlencoded::parse(v.as_bytes()).into_owned().collect()
|
||||
}).unwrap_or_else(HashMap::new);
|
||||
let order_id = params.get("id");
|
||||
|
||||
"DELETE FROM orders WHERE order_id=:order_id"
|
||||
.with(params! { "order_id" => order_id, })
|
||||
.ignore(&mut conn)
|
||||
.await?;
|
||||
|
||||
drop(conn);
|
||||
Ok(response_build("{\"status\":true}"))
|
||||
}
|
||||
|
||||
// Return the 404 Not Found for other routes.
|
||||
_ => {
|
||||
let mut not_found = Response::default();
|
||||
*not_found.status_mut() = StatusCode::NOT_FOUND;
|
||||
Ok(not_found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CORS headers
|
||||
fn response_build(body: &str) -> Response<Body> {
|
||||
Response::builder()
|
||||
.header("Access-Control-Allow-Origin", "*")
|
||||
.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
|
||||
.header("Access-Control-Allow-Headers", "api,Keep-Alive,User-Agent,Content-Type")
|
||||
.body(Body::from(body.to_owned()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
let opts = Opts::from_url(&*get_url()).unwrap();
|
||||
let builder = OptsBuilder::from_opts(opts);
|
||||
// The connection pool will have a min of 5 and max of 10 connections.
|
||||
let constraints = PoolConstraints::new(5, 10).unwrap();
|
||||
let pool_opts = PoolOpts::default().with_constraints(constraints);
|
||||
let pool = Pool::new(builder.pool_opts(pool_opts));
|
||||
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
|
||||
let make_svc = make_service_fn(|_| {
|
||||
let pool = pool.clone();
|
||||
async move {
|
||||
Ok::<_, Infallible>(service_fn(move |req| {
|
||||
let pool = pool.clone();
|
||||
handle_request(req, pool)
|
||||
}))
|
||||
}
|
||||
});
|
||||
let server = Server::bind(&addr).serve(make_svc);
|
||||
if let Err(e) = server.await {
|
||||
eprintln!("server error: {}", e);
|
||||
}
|
||||
Ok(())
|
||||
}
|
25
wasmedge-mysql-nginx/compose.yml
Normal file
25
wasmedge-mysql-nginx/compose.yml
Normal file
|
@ -0,0 +1,25 @@
|
|||
services:
|
||||
frontend:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- 8090:80
|
||||
volumes:
|
||||
- ./frontend:/usr/share/nginx/html
|
||||
|
||||
backend:
|
||||
image: demo-microservice
|
||||
platform: wasi/wasm
|
||||
build:
|
||||
context: backend/
|
||||
ports:
|
||||
- 8080:8080
|
||||
environment:
|
||||
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
|
||||
RUST_BACKTRACE: full
|
||||
restart: unless-stopped
|
||||
runtime: io.containerd.wasmedge.v1
|
||||
|
||||
db:
|
||||
image: mariadb:10.9
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: whalehello
|
47
wasmedge-mysql-nginx/db/orders.json
Normal file
47
wasmedge-mysql-nginx/db/orders.json
Normal file
|
@ -0,0 +1,47 @@
|
|||
[
|
||||
{
|
||||
"order_id": 1,
|
||||
"product_id": 12,
|
||||
"quantity": 2,
|
||||
"amount": 56.0,
|
||||
"shipping": 15.0,
|
||||
"tax": 2.0,
|
||||
"shipping_address": "Mataderos 2312"
|
||||
},
|
||||
{
|
||||
"order_id": 2,
|
||||
"product_id": 15,
|
||||
"quantity": 3,
|
||||
"amount": 256.0,
|
||||
"shipping": 30.0,
|
||||
"tax": 16.0,
|
||||
"shipping_address": "1234 NW Bobcat"
|
||||
},
|
||||
{
|
||||
"order_id": 3,
|
||||
"product_id": 11,
|
||||
"quantity": 5,
|
||||
"amount": 536.0,
|
||||
"shipping": 50.0,
|
||||
"tax": 24.0,
|
||||
"shipping_address": "20 Havelock"
|
||||
},
|
||||
{
|
||||
"order_id": 4,
|
||||
"product_id": 8,
|
||||
"quantity": 8,
|
||||
"amount": 126.0,
|
||||
"shipping": 20.0,
|
||||
"tax": 12.0,
|
||||
"shipping_address": "224 Pandan Loop"
|
||||
},
|
||||
{
|
||||
"order_id": 5,
|
||||
"product_id": 24,
|
||||
"quantity": 1,
|
||||
"amount": 46.0,
|
||||
"shipping": 10.0,
|
||||
"tax": 2.0,
|
||||
"shipping_address": "No.10 Jalan Besar"
|
||||
}
|
||||
]
|
9
wasmedge-mysql-nginx/db/update_order.json
Normal file
9
wasmedge-mysql-nginx/db/update_order.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"order_id": 3,
|
||||
"product_id": 12,
|
||||
"quantity": 2,
|
||||
"amount": 56.0,
|
||||
"shipping": 15.0,
|
||||
"tax": 2.0,
|
||||
"shipping_address": "123 Main Street"
|
||||
}
|
102
wasmedge-mysql-nginx/frontend/index.html
Normal file
102
wasmedge-mysql-nginx/frontend/index.html
Normal file
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Demo App</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous" />
|
||||
<style>.d-none { display: none; }</style>
|
||||
</head>
|
||||
<body class="mb-5">
|
||||
<div class="container mt-5">
|
||||
<div id="app-loading-display">
|
||||
<h1>Loading...</h1>
|
||||
</div>
|
||||
|
||||
<div id="order-display" class="d-none">
|
||||
<h1>Welcome to the Demo!</h1>
|
||||
<p>This application is served using nginx for the website, Wasm for the backend, and MariaDB for the database.</p>
|
||||
|
||||
<div id="order-empty-text" class="d-none">
|
||||
<em>There are currently no orders to display!</em>
|
||||
</div>
|
||||
|
||||
<table id="order-table" class="d-none table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Product Id</th>
|
||||
<th>Quantity</th>
|
||||
<th>Amount</th>
|
||||
<th>Shipping</th>
|
||||
<th>Tax</th>
|
||||
<th>Address</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
|
||||
<hr />
|
||||
|
||||
<div id="add-order-wrapper" class="d-none row">
|
||||
<div class="col-6">
|
||||
<div class="accordion" id="accordionExample">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="addOrderHeading">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#addOrder" aria-controls="addOrder">
|
||||
Add an order
|
||||
</button>
|
||||
</h2>
|
||||
|
||||
<div id="addOrder" class="accordion-collapse collapse p-3" aria-labelledby="addOrderHeading" data-bs-parent="#accordionExample">
|
||||
<form id="add-order-form">
|
||||
<div class="mb-3">
|
||||
<label for="order-id" class="form-label">Order Id</label>
|
||||
<input type="number" required class="form-control" id="order-id" aria-describedby="orderIdHelp">
|
||||
<div id="orderIdHelp" class="form-text">The ID of the order</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="product-id" class="form-label">Product Id</label>
|
||||
<input type="number" required class="form-control" id="product-id" aria-describedby="productIdHelp">
|
||||
<div id="productIdHelp" class="form-text">The ID of the product</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="quantity" class="form-label">Quantity</label>
|
||||
<input type="number" required class="form-control" id="quantity" aria-describedby="quantityHelp">
|
||||
<div id="quantityHelp" class="form-text">How many of the product?</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="amount" class="form-label">Amount</label>
|
||||
<input type="number" required class="form-control" id="amount" aria-describedby="amountHelp">
|
||||
<div id="amountHelp" class="form-text">The total amount</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="tax" class="form-label">Tax</label>
|
||||
<input type="number" required class="form-control" id="tax" aria-describedby="taxHelp">
|
||||
<div id="taxHelp" class="form-text">The total amount of tax</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shippingAmount" class="form-label">Shipping Amount</label>
|
||||
<input type="number" required class="form-control" id="shippingAmount" aria-describedby="shippingAmountHelp">
|
||||
<div id="shippingAmountHelp" class="form-text">The total amount for shipping</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="shippingAddress" class="form-label">Shipping Address</label>
|
||||
<input type="text" required class="form-control" id="shippingAddress" aria-describedby="addressHelp">
|
||||
<div id="addressHelp" class="form-text">Where to send the order</div>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn btn-success" value="Add Order" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
135
wasmedge-mysql-nginx/frontend/js/app.js
Normal file
135
wasmedge-mysql-nginx/frontend/js/app.js
Normal file
|
@ -0,0 +1,135 @@
|
|||
(function() {
|
||||
let orders = null;
|
||||
const appLoadingEle = document.getElementById("app-loading-display");
|
||||
const orderWrapperEle = document.getElementById("order-display");
|
||||
const orderEmptyTextEle = document.getElementById("order-empty-text");
|
||||
const orderTableEle = document.getElementById("order-table");
|
||||
const orderTableBodyEle = document.querySelector("#order-table tbody");
|
||||
const addOrderEle = document.getElementById("add-order-wrapper");
|
||||
const addOrderForm = document.getElementById("add-order-form");
|
||||
|
||||
const orderIdField = document.getElementById("order-id");
|
||||
const productIdField = document.getElementById("product-id");
|
||||
const quantityField = document.getElementById("quantity");
|
||||
const amountField = document.getElementById("amount");
|
||||
const taxField = document.getElementById("tax");
|
||||
const shippingField = document.getElementById("shippingAmount");
|
||||
const shippingAddressField = document.getElementById("shippingAddress");
|
||||
|
||||
function fetchOrders() {
|
||||
fetch("http://localhost:8080/orders")
|
||||
.then(r => r.json())
|
||||
.then(r => orders = r)
|
||||
.then(renderOrders)
|
||||
.catch((e) => {
|
||||
init();
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
fetch("http://localhost:8080/init")
|
||||
.then(() => fetchOrders())
|
||||
.catch((e) => displayError(e));
|
||||
}
|
||||
|
||||
function renderOrders() {
|
||||
appLoadingEle.classList.add("d-none");
|
||||
orderWrapperEle.classList.remove("d-none");
|
||||
addOrderEle.classList.remove("d-none");
|
||||
|
||||
if (orders.length === 0) {
|
||||
orderEmptyTextEle.classList.remove("d-none");
|
||||
orderTableEle.classList.add("d-none");
|
||||
return;
|
||||
}
|
||||
|
||||
orderEmptyTextEle.classList.add("d-none");
|
||||
orderTableEle.classList.remove("d-none");
|
||||
|
||||
while (orderTableBodyEle.firstChild) {
|
||||
orderTableBodyEle.removeChild(orderTableBodyEle.firstChild);
|
||||
}
|
||||
|
||||
orders.forEach((order) => {
|
||||
const orderId = order.order_id;
|
||||
|
||||
const row = document.createElement("tr");
|
||||
|
||||
row.appendChild(createCell(order.order_id));
|
||||
row.appendChild(createCell(order.product_id));
|
||||
row.appendChild(createCell(order.quantity));
|
||||
row.appendChild(createCell(order.amount));
|
||||
row.appendChild(createCell(order.shipping));
|
||||
row.appendChild(createCell(order.tax));
|
||||
row.appendChild(createCell(order.shipping_address));
|
||||
|
||||
const actionCell = document.createElement("td");
|
||||
|
||||
const deleteButton = document.createElement("button");
|
||||
deleteButton.classList.add(...["btn","btn-sm","btn-danger"]);
|
||||
deleteButton.innerText = "Delete";
|
||||
|
||||
deleteButton.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
deleteOrder(orderId);
|
||||
});
|
||||
|
||||
actionCell.appendChild(deleteButton);
|
||||
|
||||
row.appendChild(actionCell);
|
||||
|
||||
orderTableBodyEle.appendChild(row);
|
||||
});
|
||||
}
|
||||
|
||||
function createCell(contents) {
|
||||
const cell = document.createElement("td");
|
||||
cell.innerText = contents;
|
||||
return cell;
|
||||
}
|
||||
|
||||
function deleteOrder(orderId) {
|
||||
fetch(`http://localhost:8080/delete_order?id=${orderId}`)
|
||||
.then(() => fetchOrders());
|
||||
}
|
||||
|
||||
function displayError(err) {
|
||||
alert("Error:" + err);
|
||||
}
|
||||
|
||||
function onAddFormSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const data = {
|
||||
order_id : parseFloat(orderIdField.value),
|
||||
product_id : parseFloat(productIdField.value),
|
||||
quantity : parseFloat(quantityField.value),
|
||||
amount : parseFloat(amountField.value),
|
||||
shipping : parseFloat(shippingField.value),
|
||||
tax : parseFloat(taxField.value),
|
||||
shipping_address : shippingAddressField.value,
|
||||
};
|
||||
|
||||
fetch("http://localhost:8080/create_order", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
headers: { "Content-type": "application/json" },
|
||||
}).then(() => fetchOrders())
|
||||
.then(() => resetAddOrderForm());
|
||||
|
||||
alert("Order added");
|
||||
}
|
||||
|
||||
function resetAddOrderForm() {
|
||||
orderIdField.value = "";
|
||||
productIdField.value = "";
|
||||
quantityField.value = "";
|
||||
amountField.value = "";
|
||||
shippingField.value = "";
|
||||
taxField.value = "";
|
||||
shippingAddressField.value = "";
|
||||
}
|
||||
|
||||
fetchOrders();
|
||||
addOrderForm.addEventListener("submit", onAddFormSubmit);
|
||||
})();
|
Loading…
Reference in a new issue