Giter VIP home page Giter VIP logo

lucee-dockerfiles's Introduction

Lucee Docker Images

This repository focuses on building and maintaining the Lucee Docker Images provided for Lucee.

Build Lucee Docker Images docker pulls

Lucee application engine running on Apache Tomcat J2EE application server.

Supported tags and respective Dockerfile links

Latest stable release

Lucee 6.0.x - Tomcat 9.0 with Java 11 (recommended)

  • 6.0.3.1-tomcat9.0-jre11-temurin-jammy, 6.0.3.1, 6.0, latest (Dockerfile)
    • 6.0.3.1-nginx-tomcat9.0-jre11-temurin-jammy, 6.0.3.1-nginx, 6.0-nginx (Dockerfile.nginx)

Previous stable release (LTS)

Lucee 5.4.x - Tomcat 9.0 with Java 11 (recommended)

  • 5.4.5.23-tomcat9.0-jre11-temurin-jammy, 5.4.5.23, 5.4 (Dockerfile)
    • 5.4.5.23-nginx-tomcat9.0-jre11-temurin-jammy, 5.4.5.23-nginx, 5.4-nginx (Dockerfile.nginx)

Lucee 5.4.x - Tomcat 9.0 with Java 8

Bleeding edge Snapshot / RC / Beta

  • 6.1.0.193-RC-tomcat9.0-jre21-temurin-jammy, 6.1.0.193-RC
    • 6.1.0.193-RC-nginx-tomcat9.0-jre21-temurin-jammy, 6.1.0.193-RC-nginx
  • 6.0.2.41-RC-tomcat9.0-jre11-temurin-jammy, 6.0.2.41-RC
    • 6.0.2.41-RC-nginx-tomcat9.0-jre11-temurin-jammy, 6.0.2.41-RC-nginx

The SNAPSHOTS Docker image builds are automatically generated after a successful Lucee build. Check the Docker Hub tags and/or the Lucee Downloads page to see the latest SNAPSHOT version numbers.

The RC and Beta builds are manually triggered when they are announced.

For more information about Lucee versions and extensions see the Lucee Downloads page.

How the tags work

The Lucee Docker image tags follow a naming convention which is used to produce "simple tags" that are updated with each release (e.g. 6.1, 6.1-nginx) as well as "full tags" which allow for very specific version targeting (e.g. 6.1.0.175-tomcat9.0-jre21-temurin-jammy).

The tag naming convention is;

LUCEE_VERSION[-RELEASE_TYPE][-light][-nginx][-TOMCAT_VERSION-JRE_VERSION]

  • LUCEE_VERSION is the Lucee Version number string. For simple tags it may optionally be in the MAJOR.MINOR format (e.g. 5.4) and for full tags it's in the MAJOR.MINOR.PATCH.BUILD format (e.g. 6.1.0.175). Snapshot, RC and Beta builds always include the full version number.
  • RELEASE_TYPE is the type of release; omitted for Releases, otherwise SNAPSHOT, RC or BETA
  • -light (optional) is a build with the Lucee "Light" JAR file, WITHOUT any extensions (users must install extensions separately, this includes database drivers, ORM, ESAPI, S3, image handling, etc)
  • -nginx (optional) is a build with the NGINX web server bundled and configured
  • -TOMCAT_VERSION-JRE_VERSION is the Tomcat major and minor version and Java major version of the build to allow users to choose between different combinations (e.g. tomcat9.0-jre11-temurin-jammy vs tomcat9.0-jre21-temurin-jammy). This is omitted for "simple tags" where the recommended Tomcat and Java versions are used.

Base Image / Operating System Notes:

  • The Lucee images are based on the Docker Tomcat images.
  • The Docker Tomcat images were previously based on OpenJDK images which used Debian as the underlying OS. The OpenJDK Debian images have been discontinued for Java 8 and Java 11 so the next best match in the Docker Tomcat images are now the Ubuntu Jammy (22.04 LTS) and Focal (20.04 LTS) images using the OpenJDK baed Temurin Java distributions.
  • The Docker Tomcat images removed support for Alpine and so the Lucee -alpine variant can no longer be supported. If the Tomcat base images add support for Alpine in the future then we will look to support the -alpine variant again.

Example Project Dockerfile

For the latest stable release with Tomcat only:

FROM lucee/lucee:6.0

COPY config/lucee/ /opt/lucee/web/
COPY www /var/www

For the latest stable release with NGINX and Tomcat:

FROM lucee/lucee:6.0-nginx

COPY config/nginx/ /etc/nginx/
COPY config/lucee/ /opt/lucee/web/
COPY www /var/www

More examples here

Features

Java optimisation tweaks

Optimised for single-site application

The default configuration serves a single application for any hostname on the listening port. Multiple applications can be supported by editing the server.xml in the Tomcat config.

Lucee 6 by default runs in single mode (only one configuration and Administrator), if you prefer to run it in multi mode you need to to set the flag "mode" to "multi" in the of the .CFConfig.json file.

Using this image

Accessing the service

Lucee server's Tomcat installation listens on port 8888, and optional NGINX listens on port 80.

This base image exposes port 8080 to linked containers but its not used. You must publish or expose port 8888 if you wish to access Tomcat from your installation.

Accessing the Lucee Admin

The Lucee Admin URL is /lucee/admin/ from the exposed port. With Lucee 5.4.6 (and above), 6.0.2 (and above) and 6.1 (and above), you can set the password with the environment variable LUCEE_ADMIN_PASSWORD=qwerty or the system property -Dlucee.admin.password=123456.

THIS IS NOT A SECURE CONFIGURATION FOR PRODUCTION ENVIRONMENTS! It is strongly recommended that you secure the container by:

  • Changing the server password
  • Using IP or URL filtering to restrict access to the Lucee Admin
  • Following recommended security practices such as the Lucee Lockdown Guide

The NGINX tagged Docker images are configured to deny access to the Lucee Admin by default in the default.conf.

Folder locations

Web root for default site: /var/www

Configuration folders:

  • Tomcat config: /usr/local/tomcat/conf
  • Lucee config for default site: /opt/lucee/web
  • Lucee server context: /opt/lucee/server/lucee-server/context

Log folders:

  • Tomcat logs: /usr/local/tomcat/logs
  • Lucee logs for default site: /opt/lucee/web/logs

Environment variables

Following some helpful Environment variables you can use with the Lucee docker image.

  • LUCEE_ADMIN_PASSWORD: The password for the Lucee Administrator
  • LUCEE_VERSION: If set Lucee will run this version independent of the version installed.
  • LUCEE_JAVA_OPTS: Additional JVM parameters for Tomcat. Used by /usr/local/tomcat/bin/setenv.sh. Default: "-Xms64m -Xmx512m".

For all possible enviroment variables supported by Lucee, see here.

How to locally develop Lucee Docker builds

Developing and testing builds locally requires a Docker environment with buildx support and Python 3 installed. Run pip3 install -r requirements.txt to install the required dependencies.

To build and test specific verions set environment variables for the Tomcat and Lucee verions that are to be used, e.g.

export TOMCAT_VERSION=9.0
export TOMCAT_JAVA_VERSION=jre11-temurin-jammy
export TOMCAT_BASE_IMAGE=
export LUCEE_MINOR=5.4
export LUCEE_SERVER=,-nginx
export LUCEE_VARIANTS=

export LUCEE_VERSION=5.4.4.38

Then use the default builder with buildx and run the build-images script using a single target platform only (matching your native platform), e.g.

docker buildx use default
./build-images.py --no-push --buildx-load --buildx-platform linux/amd64

Specify the newly built image tag in a Docker Compose file to run and test the container image with docker-compose up;

lucee:
  image: lucee/lucee:5.4.4.38
  ports: 
    - "8854:8888"
    - "8054:80"

You can also find examples that show you how to for example add your own configuration or custom extensions here

Advanced build changes

If adding new Tomcat base (OS) images, Tomcat versions, Java versions, or Lucee versions or variants, the matrix.yaml needs to be edited so that several features like the tag building/lookups will work. After modifying the matrix.yaml run the script ./generate-matrix.py to generate the new Travis configuration (note: Travis CI is deprecated as builds have transitioned to GitHub Actions, however this part of the build hasn't been fully removed yet).

Older Lucee Base Images

The older versions of Lucee remain available as tags in the lucee/lucee Docker Hub repository. Listed are the newest releases for each minor version.

Lucee 5.3.x - Tomcat 9.0 with Java 11

  • 5.3.12.1-tomcat9.0-jre11-temurin-jammy, 5.3.12.1, 5.3 (Dockerfile)
    • 5.3.12.1-nginx-tomcat9.0-jre11-temurin-jammy, 5.3.12.1-nginx, 5.3-nginx (Dockerfile.nginx)

Lucee 5.2.x - Tomcat 9.0 with Java 11

  • 5.2.9.31-tomcat9.0-jre11, 5.2.9.31, 5.2 (Dockerfile)

Legacy Lucee Base Images

The legacy Lucee Base Images / repositories will remain available for the projects that are using them, though the build process for those images is considered "legacy" as they have been superseded by the new build matrix builds.

The base images can be accessed in the existing Docker Hub repositories and the source is now in the legacy branch;

https://github.com/lucee/lucee-dockerfiles/tree/legacy

Lucee 5.2 (Legacy builds)

Lucee 5.1 (Legacy builds)

Lucee 5.0 (Legacy builds)

Lucee 4.5 (Legacy builds)

Contributing to this Project

The Lucee Dockerfiles project is maintained by the community. Chief protagonist is @justincarter (Justin Carter of Daemon). Bug reports and pull requests are most welcome.

Special thanks to @rye (Kristofer Rye) and @hawkrives (Hawken Rives) for their work on the Travis build matrix.

License

The Docker files and config files are available under the MIT License. The Lucee engine, Tomcat, NGINX and any other softwares are available under their respective licenses.

lucee-dockerfiles's People

Contributors

andyj avatar boomfish avatar carehart avatar dependabot[bot] avatar goochjj avatar jamiejackson avatar justincarter avatar michaeloffner avatar modius avatar ryanguill avatar rye avatar tomchiverton avatar zspitzer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lucee-dockerfiles's Issues

Keep Images Up to Date

Consider that the lucee/lucee4 image hasn't seen an update in over a year, but IIRC, there have been several Tomcat CVEs in the meantime.

The community assumes that supported tags are kept up-to-date.

This is somewhat related to #40.

Use Conventional Image Version Tagging

Currently, each Lucee minor version has its own Docker Hub repo; however, this is counterintuitive/unconventional.

For instance lucee/lucee5 should (at the time of this writing) be equivalent to:

  • lucee/latest
  • lucee/5.2
  • lucee/5.2.6

Examples of projects that use conventional versioning:

This would require more build plumbing, as noted by @justincarter (on Slack):

@jamiejackson yes each lucee minor version does have it's own repo in docker hub, for the primary reason that we're using automated build triggers

if we drop the docker hub automated build triggers and build a more complex pipeline then we could automate the builds of various different combinations of base image, tomcat version, java version, lucee version
the amount of work to get to that point hasn't quite been justified yet, or i haven't had enough free time 🙂
so to upgrade from lucee 5.1 to 5.2 you'd change FROM lucee/lucee51-nginx:latest to FROM lucee/lucee52-nginx:latest

you can see the kinds of additional tools/scripts that need to be implemented for the solr image builds here:
https://github.com/docker-solr/docker-solr/tree/afe43e97be7aa764656f3e0aa068bed90f6bdd27/tools

Tomcat process runs as ROOT within container

nginx is properly configured to drop privileges and run as www-data

The generic tomcat images do NOT create a tomcat service account. It's relatively trivial to create your own, and run as that user, but the default Docker Community images don't provide it.

While containers do have some levels of isolation it's best practice to NOT run internet accessible services as root, whether they're in a container or not.

RC builds not current?

The latest RC listed at https://download.lucee.org/ is currently 5.3.4.54 (Sept 9, 2019), but the latest RC image I see is a couple RCs ago (from April).

$ wget -q https://registry.hub.docker.com/v1/repositories/lucee/lucee/tags -O -  | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n'  | awk -F: '{print $3}' | grep RC | grep 5.3
5.3.1.87-RC
5.3.1.87-RC-light
5.3.1.87-RC-light-nginx
5.3.1.87-RC-light-nginx-tomcat9.0-jre11
5.3.1.87-RC-light-nginx-tomcat9.0-jre8
5.3.1.87-RC-light-nginx-tomcat9.0-jre8-alpine
5.3.1.87-RC-light-tomcat9.0-jre11
5.3.1.87-RC-light-tomcat9.0-jre8
5.3.1.87-RC-light-tomcat9.0-jre8-alpine
5.3.1.87-RC-nginx
5.3.1.87-RC-nginx-tomcat9.0-jre11
5.3.1.87-RC-nginx-tomcat9.0-jre8
5.3.1.87-RC-nginx-tomcat9.0-jre8-alpine
5.3.1.87-RC-tomcat9.0-jre11
5.3.1.87-RC-tomcat9.0-jre8
5.3.1.87-RC-tomcat9.0-jre8-alpine
5.3.1.94-RC
5.3.1.94-RC-light
5.3.1.94-RC-light-nginx
5.3.1.94-RC-light-nginx-tomcat9.0-jre11
5.3.1.94-RC-light-nginx-tomcat9.0-jre8
5.3.1.94-RC-light-nginx-tomcat9.0-jre8-alpine
5.3.1.94-RC-light-tomcat9.0-jre11
5.3.1.94-RC-light-tomcat9.0-jre8
5.3.1.94-RC-light-tomcat9.0-jre8-alpine
5.3.1.94-RC-nginx
5.3.1.94-RC-nginx-tomcat9.0-jre11
5.3.1.94-RC-nginx-tomcat9.0-jre8
5.3.1.94-RC-nginx-tomcat9.0-jre8-alpine
5.3.1.94-RC-tomcat9.0-jre11
5.3.1.94-RC-tomcat9.0-jre8
5.3.1.94-RC-tomcat9.0-jre8-alpine
5.3.2.74-RC
5.3.2.74-RC-light
5.3.2.74-RC-light-nginx
5.3.2.74-RC-light-nginx-tomcat9.0-jre11
5.3.2.74-RC-light-nginx-tomcat9.0-jre8
5.3.2.74-RC-light-nginx-tomcat9.0-jre8-alpine
5.3.2.74-RC-light-tomcat9.0-jre11
5.3.2.74-RC-light-tomcat9.0-jre8
5.3.2.74-RC-light-tomcat9.0-jre8-alpine
5.3.2.74-RC-nginx
5.3.2.74-RC-nginx-tomcat9.0-jre11
5.3.2.74-RC-nginx-tomcat9.0-jre8
5.3.2.74-RC-nginx-tomcat9.0-jre8-alpine
5.3.2.74-RC-tomcat9.0-jre11
5.3.2.74-RC-tomcat9.0-jre8
5.3.2.74-RC-tomcat9.0-jre8-alpine

Tomcat should be configured for port 8080

We moved the internal Tomcat port to 8888 to match the installer set up for Lucee servers. Unfortunately, the base Tomcat image exposes port 8080 by default, and this cannot be removed without building or own Tomcat base.

Might be better to follow Tomcat best practice and have port 8080 as the exposed port on our installation rather than 8888 which appears to be fairly specific to Lucee installers.

no valid OpenPGP data found.

Hi,

Haven't seen this one before. I am not behind a proxy.

command line...

$ docker-compose  up -d
Building lucee
Step 1/15 : FROM lucee/lucee5:latest
# Executing 1 build trigger...
Step 1/1 : RUN rm -rf /var/www/*
 ---> Using cache
 ---> 3ae29167becc
Step 2/15 : MAINTAINER Geoff Bowers <[email protected]>
 ---> Using cache
 ---> 21617fdc240c
Step 3/15 : RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
 ---> Running in 3114b4e2885d
Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.YCWlCExEp1 --no-auto-check-trustdb --trust-model always --primary-keyring /etc/apt/trusted.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-jessie-automatic.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-jessie-security-automatic.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-jessie-stable.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-squeeze-automatic.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-squeeze-stable.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-wheezy-automatic.gpg --keyring /etc/apt/trusted.gpg.d/debian-archive-wheezy-stable.gpg --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
gpg: requesting key 7BD9BF62 from hkp server pgp.mit.edu
gpgkeys: key 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 can't be retrieved
gpg: no valid OpenPGP data found.
gpg: Total number processed: 0
ERROR: Service 'lucee' failed to build: The command '/bin/sh -c apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62' returned a non-zero code: 2

Can't boot up Vagrant

I have vagrant 1.7.4, installed vagrant workbench.

vagrant up dockerhost works ok
with "vagrant up lucee45" produces the error:

There are errors in the configuration of this machine. Please fix
the following errors and try again:

vm:
* A box must be specified.

How can't I fix it ? Thanks

CFFTP fails inside docker container

EDIT - I did an apt-get install ftp directly on my lucee container and found out a directory listing will only work in passive mode via command line. So this leads me to believe passive = "true" option does not work for CFFTP? Can anyone else reproduce this issue?

I have not been able to complete simple ftp operations within lucee-nginx 4.5 docker container tag - 4.5.3-t8.0.36. I even tried rolling back to the first docker image 4.5.1.024 with no luck. After troubleshooting multiple external and internal ftp connections, I believe the core issue to be at the docker container both from a docker virtual machine and running docker on linux. I have been able to get cfftp to work as expected running on my windows box using the express installer for 4.5. The error messages make me think it has something to do with networking from docker. I receive an ftp security deny response from the remote ftp server when doing file transfers or directory list actions (connection open/close and create directory work fine). Here are some of the error messages I get for a directory list action:

FTP server running locally: 425 Can't open data connection for transfer of "/"
FTP server running remotely: 500 I won't open a connection to 172.19.0.2 (only to 24.252.XX.XXX)

I partially masked my external IP 24.252.XX.XXX - so that last error looks as if the Lucee sent my local ip instead of my external ip address when running inside docker. I would not be surprised if all versions docker images for Lucee is affected by this CFFTP issue. Please let me know if there is any config change I can make to solve this or if this is a bigger issue. For me this is a show stopping bug to avoid using lucee docker images, ftp is a must have. Thanks for looking into this.

Here is sample code to reproduce the issue:

<cfoutput>
<!--- Open the connection. ---> 

<cfftp action = "open" 
    username = "myuser" 
    connection = "myConn" 
    password = "mypass" 
    server = "ftp.example.com" 
    port = "21"
    passive = "true">

<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput> 
<cfdump var="#cfftp#" label="connection"> 

<cfset dirExists = false>
<cfftp
    action="existsDir"
    connection="myConn"
    directory="/" stoponerror="no">
<cfif cfftp.ReturnValue eq true>
    <cfset dirExists = true>
</cfif>
<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput>
<cfdump var="#dirExists#">

<cfftp action = "listdir" 
    connection="myConn" 
    stopOnError="yes" 
    name="ListFiles" 
    directory="/"> 

<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput> 
<cfdump var="#ListFiles#">

<!--- Close the connection. ---> 
<cfftp action="close" connection="myConn">
</cfoutput>

How to deal with TOMCAT CVE-2020-1938: Ghostcat (AJP)

When working with a recent snapshot/RC (5.3.5.80-SNAPSHOT-tomcat9.0-jdk11-openjdk), I saw some oddities in my logs:

 NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
 org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.31
 org.apache.catalina.startup.VersionLoggerListener.log Server built:          Feb 5 2020 19:32:12 UTC
 org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.31.0
 org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
 org.apache.catalina.startup.VersionLoggerListener.log OS Version:            4.15.0-88-generic
 org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
 org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-11
 org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.6+10
 org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
 org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
 org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xms512m
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Xmx4096m
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.security.egd=file:/dev/./urandom
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
 org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
 org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.23] using APR version [1.6.5].
 org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
 org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
 org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1d  10 Sep 2019]
 org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8888"]
 org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-127.0.0.1-8009"]
 org.apache.catalina.startup.Catalina.load Server initialization in [5,640] milliseconds
 org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
 org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.31]
 WARNING: An illegal reflective access operation has occurred
 WARNING: Illegal reflective access by org.apache.felix.framework.ext.ClassPathExtenderFactory$DefaultClassLoaderExtender (file:/usr/local/tomcat/lucee/lucee.jar) to method java.net.URLClassLoader.addURL(java.net.URL)
 WARNING: Please consider reporting this to the maintainers of org.apache.felix.framework.ext.ClassPathExtenderFactory$DefaultClassLoaderExtender
 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
 WARNING: All illegal access operations will be denied in a future release
 12-Mar-2020 17:40:14.774 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8888"]
 12-Mar-2020 17:40:14.871 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to start component [Connector[AJP/1.3-8009]]
 	org.apache.catalina.LifecycleException: Protocol handler start failed
 		at org.apache.catalina.connector.Connector.startInternal(Connector.java:1038)
 		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
 		at org.apache.catalina.core.StandardService.startInternal(StandardService.java:438)
 		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
 		at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
 		at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
 		at org.apache.catalina.startup.Catalina.start(Catalina.java:633)
 		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 		at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 		at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 		at java.base/java.lang.reflect.Method.invoke(Method.java:566)
 		at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343)
 		at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474)
 	Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
 		at org.apache.coyote.ajp.AbstractAjpProtocol.start(AbstractAjpProtocol.java:264)
 		at org.apache.catalina.connector.Connector.startInternal(Connector.java:1035)
 		... 12 more
 org.apache.catalina.startup.Catalina.start Server startup in [14,192] milliseconds
 org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8888"]
 org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["ajp-nio-8009"]
 org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
 org.apache.catalina.core.StandardWrapper.unload Waiting for [1] instance(s) to be deallocated for Servlet [CFMLServlet]
 org.apache.catalina.core.StandardWrapper.unload Waiting for [1] instance(s) to be deallocated for Servlet [CFMLServlet]
 org.apache.catalina.core.StandardWrapper.unload Waiting for [1] instance(s) to be deallocated for Servlet [CFMLServlet]
 org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8888"]
 12-Mar-2020 17:40:34.595 SEVERE [http-nio-8888-exec-10] org.apache.coyote.http11.Http11Processor.service Error processing request
 	java.lang.NullPointerException
 		at org.apache.coyote.http11.Http11OutputBuffer.commit(Http11OutputBuffer.java:306)
 		at org.apache.coyote.http11.Http11Processor.prepareResponse(Http11Processor.java:986)
 		at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:369)
 		at org.apache.coyote.Response.action(Response.java:211)
 		at org.apache.coyote.Response.sendHeaders(Response.java:437)
 		at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:281)
 		at org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:241)
 		at org.apache.catalina.connector.Response.finishResponse(Response.java:441)
 		at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:374)
 		at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
 		at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
 		at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836)
 		at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1839)
 		at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
 		at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
 		at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
 		at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
 		at java.base/java.lang.Thread.run(Thread.java:834)
 org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["ajp-nio-8009"]
 org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-8888"]
 org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["ajp-nio-8009"]
 System property [org.owasp.esapi.opsteam] is not set
 System property [org.owasp.esapi.devteam] is not set

Here's the bit I'm looking into: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.

That led me here: https://dev.lucee.org/t/tomcat-cve-2020-1938-ghostcat-ajp

I haven't gone completely down the rabbit hole yet, but a few things:

  • Does this matter if I have a secondary web server (HTTPD) out front proxying requests to my lucee service? That's my situation now. (But I have pretty imminent plans to use an official Lucee image that bundles nginx because I'm tired of the hassle of keeping them separate, so I'll soon need to know about that paradigm, too.)
  • If it turns out that a secret is necessary, we should build some capability into the image to handle the plumbing (rather than requiring users to hand-roll xml patching routines).

Thoughts?

An illegal reflective access operation has occurred

About 5.3.77-nginx: While starting tomcat and lucee as non root.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.felix.framework.ext.ClassPathExtenderFactory$DefaultClassLoaderExtender (file:/usr/local/tomcat/lucee/lucee.jar) to method java.net.URLClassLoader.addURL(java.net.URL)
WARNING: Please consider reporting this to the maintainers of org.apache.felix.framework.ext.ClassPathExtenderFactory$DefaultClassLoaderExtender
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
ERROR: Error creating bundle cache.

That's resolved with the latest, felix.framework-6.0.3?
http://svn.apache.org/repos/asf/felix/releases/org.apache.felix.framework-6.0.3/doc/changelog.txt

Need Image Rebuild to Patch Vulnerabilities

I think the SOP is to do periodic matrix rebuilds to pick up patches from base images.

Latest:

image

Name Package Severity Description
CVE-2020-10878 perl:5.28.1-6 HIGH Perl before 5.30.3 has an integer overflow related to mishandling of a "PL_regkind[OP(n)] == NOTHING" situation. A crafted regular expression could lead to malformed bytecode with a possibility of instruction injection.
CVE-2020-8492 python2.7:2.7.16-2+deb10u1 HIGH Python 2.7 through 2.7.17, 3.5 through 3.5.9, 3.6 through 3.6.10, 3.7 through 3.7.6, and 3.8 through 3.8.1 allows an HTTP server to conduct Regular Expression Denial of Service (ReDoS) attacks against a client because of urllib.request.AbstractBasicAuthHandler catastrophic backtracking.
CVE-2018-12886 gcc-8:8.3.0-6 MEDIUM stack_protect_prologue in cfgexpand.c and stack_protect_epilogue in function.c in GNU Compiler Collection (GCC) 4.1 through 8 (under certain circumstances) generate instruction sequences when targeting ARM targets that spill the address of the stack protector guard, which allows an attacker to bypass the protection of -fstack-protector, -fstack-protector-all, -fstack-protector-strong, and -fstack-protector-explicit against stack overflow by controlling what the stack canary is compared against.
CVE-2020-1751 glibc:2.28-10 MEDIUM An out-of-bounds write vulnerability was found in glibc before 2.31 when handling signal trampolines on PowerPC. Specifically, the backtrace function did not properly check the array bounds when storing the frame address, resulting in a denial of service or potential code execution. The highest threat from this vulnerability is to system availability.
CVE-2019-20367 libbsd:0.9.1-2 MEDIUM nlist.c in libbsd before 0.10.0 has an out-of-bounds read during a comparison for a symbol name from the string table (strtab).
CVE-2019-12290 libidn2:2.0.5-1+deb10u1 MEDIUM GNU libidn2 before 2.2.0 fails to perform the roundtrip checks specified in RFC3490 Section 4.2 when converting A-labels to U-labels. This makes it possible in some circumstances for one domain to impersonate another. By creating a malicious domain that matches a target domain except for the inclusion of certain punycoded Unicode characters (that would be discarded when converted first to a Unicode label and then back to an ASCII label), arbitrary domains can be impersonated.
CVE-2019-13115 libssh2:1.8.0-2.1 MEDIUM In libssh2 before 1.9.0, kex_method_diffie_hellman_group_exchange_sha256_key_exchange in kex.c has an integer overflow that could lead to an out-of-bounds read in the way packets are read from the server. A remote attacker who compromises a SSH server may be able to disclose sensitive information or cause a denial of service condition on the client system when a user connects to the server. This is related to an _libssh2_check_length mistake, and is different from the various issues fixed in 1.8.1, such as CVE-2019-3855.
CVE-2019-20454 pcre2:10.32-5 MEDIUM An out-of-bounds read was discovered in PCRE before 10.34 when the pattern \X is JIT compiled and used to match specially crafted subjects in non-UTF mode. Applications that use PCRE to parse untrusted input may be vulnerable to this flaw, which would allow an attacker to crash the application. The flaw occurs in do_extuni_no_utf in pcre2_jit_compile.c.
CVE-2020-14155 pcre3:2:8.39-12 MEDIUM libpcre in PCRE before 8.44 allows an integer overflow via a large number after a (?C substring.
CVE-2020-12723 perl:5.28.1-6 MEDIUM regcomp.c in Perl before 5.30.3 allows a buffer overflow via a crafted regular expression because of recursive S_study_chunk calls.
CVE-2020-10543 perl:5.28.1-6 MEDIUM Perl before 5.30.3 on 32-bit platforms allows a heap-based buffer overflow because nested regular expression quantifiers have an integer overflow.
CVE-2020-11655 sqlite3:3.27.2-3 MEDIUM SQLite through 3.31.1 allows attackers to cause a denial of service (segmentation fault) via a malformed window-function query because the AggInfo object's initialization is mishandled.
CVE-2019-16168 sqlite3:3.27.2-3 MEDIUM In SQLite through 3.29.0, whereLoopAddBtreeIndex in sqlite3.c can crash a browser or other application because of missing validation of a sqlite_stat1 sz field, aka a "severe division by zero in the query planner."
CVE-2019-19603 sqlite3:3.27.2-3 MEDIUM SQLite 3.30.1 mishandles certain SELECT statements with a nonexistent VIEW, leading to an application crash.
CVE-2019-20218 sqlite3:3.27.2-3 MEDIUM selectExpander in select.c in SQLite 3.30.1 proceeds with WITH stack unwinding even after a parsing error.

dump output="console" not working?

FROM lucee/lucee4:4.5.5.006

I'm not sure if this is a problem with the image or an upstream Lucee issue, but I can't find where dump(var="hi", output="console") writes.

I've looked in:

  • /usr/local/tomcat/logs/*
  • /opt/lucee/web/logs/*.log
  • /opt/lucee/server/lucee-server/context/logs/*.log

The loss of that particular debugging tool is causing me problems.

Remove lucee admin entirely from image

While it might be beneficial in development to have access to the admin, this security risk should be removed entirely from the base image. Developers can always reinstate the admin within their own project Dockerfile.

HTTP/1.1 support for reverse proxy

Nginx uses HTTP/1.0 by default when reverse proxying. Would there be any benefit/downside to using HTTP/1.1 via proxy_http_version 1.1;?

Update Hello World template

Make a pretty hello world template. Currently dumps a few server internals for debugging, with the understanding that developers will use project specific Dockerfile to build FROM the base image.

CFDOCUMENT not working in base image

CFDOCUMENT not working as official Tomcat uses a headless openjdk that's missing the fonts and font-manager.

This can be fixed relatively easily by adding the following to the top of the Dockerfile:

# upgrade openjdk to include font tools for cfdocument
RUN apt-get update && apt-get install -y openjdk-8-jre && rm -rf /var/lib/apt/lists/*

Not sure whether this should be part of the standard build, a variant, or just advice to developers. Adding all the non-headless stuff inflates image size but is essential for folks relying on CFDOCUMENT and probably other features that need font rendering.

Remove default lucee configs from build

Currently we copy lucee config templates into the build. However, we run the risk of getting out of date with the default templates generated by the lucee build process. Should delete all lucee config defaults, and allow lucee start-up to deploy system default configs as standard.

We should be focused on providing the simplest, most reliable image for folks to build on in their own projects.

Note, this may make it harder for devs new to Docker to work out how to implement their own configs.. probably needs to be part of a more detailed documentation effort for "Getting Started with Lucee on Docker" type of thing.

stdout/stderr logging

Add basic stdout/stderr logging to supervisord to nginx 4.5 (same as 5.0).

Thanks

Need a tag for 5.3.3.65

Hello! I'm hoping to test the newly-released (a few days ago) version 5.3.3.65, but I don't see a tag for it yet. Can someone please build it?

(I'm also curious to know if there's an automated build process for these images, or if that's an area that needs work.)

Need a tag for 5.3.3.67, please

The 5.3.3.67-SNAPSHOT releases reportedly fixes a long-running bug that we've been trying to troubleshoot for months now. Please create a tag for this release. Thanks so much!

EXPOSE 8888 on Base Images

Might improve the self documenting nature of the images to EXPOSE 8888 by default now that we have determined 8888 will be the defacto standard for Tomcat for Lucee installations.

Note, it is still not possible to UNEXPOSE 8080 -- exposed by the official Tomcat base image.

Lucee 5 container dead; maven JAR distro incomplete

Current snapshot distro from maven incomplete and gives ClassNotFoundException on startup:
java.lang.ClassNotFoundException: lucee.loader.servlet.CFMLServlet

More complete stack trace below shows first error only:

02-Oct-2015 05:54:34.471 SEVERE [127.0.0.1-startStop-1] org.apache.catalina.core.StandardContext.loadOnStartup Servlet [CFMLServlet] in web application [] threw load() exception
 java.lang.ClassNotFoundException: lucee.loader.servlet.CFMLServlet
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1332)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:520)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:501)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:120)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1095)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1031)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4914)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5201)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

CGI remote address points to the proxy

The default configuration for nginx-lucee4 does not expose the correct cgi remote address (cgi.remote_addr), it points to proxy ip 127.0.0.1 - instead of the real ip. Found an article that has a fix for Railo by putting in a configuration tweak for tomcat - https://kisdigital.wordpress.com/2011/08/19/retain-remote-address-when-proxying-railo-with-nginx/

I can confirm the fix works as expected on Lucee, can someone update the tomcat config for the docker image in 4.5 and 5.0 and test out the change?

Internal Lucee Directories that Should Be Persistent

I just thought of this yesterday: There is at least one directory which probably ought to be thought of as persistent: the mail spool. If the container is recreated while there is a flaky mail connection, Lucee ought to pick up where it left off when the container restarts. This should be called out in VOLUME and documented. There may be other directories like this that I haven’t thought of, but after having lost mail for a span, this one made itself obvious.

For some unknown reason the mail queue is supposedly to be found in less than obvious /opt/lucee/web/remote-client/open directory.

Need image rebuild to update Tomcat to latest 9.0.x due to Rewrite bug

https://bz.apache.org/bugzilla/show_bug.cgi?id=64432

Currently lucee/lucee:5.3.6.61 includes Tomcat 9.0.35, as does the bleeding edge.
This version of tomcat includes the bug mentioned above, which in turn prevents using more than 1 rewrite rule within a configuration which in turn kind of breaks our servers.

Please can the image get rebuilt to the latest 9.0-jdk11-openjdk which would be 9.0.37 (released 4 days ago), or at least 9.0.36 which includes a fix for the above.

Tomcat 8.0.X end of life

Tomcat 8.0.X end of life has been announced which means there will be no more security updates/bug fixes after June 30, 2018: http://tomcat.apache.org/tomcat-80-eol.html

When will the lucee docker images be updated to Tomcat 8.5.x or even better, the 9.0.x line?
The 9.0.x line only supports Java 8, but Java 8 is close to EOL as well (January 2019)...

Review JAR scanning settings for each version of Tomcat

We have some standard JAR scanning settings (namely to skip most scanning). Need to review these in the context of both Tomcat 7 (4.5) and 8 (5.0) images. Suspect we should simply block all scanning as Lucee potentially has its own scan -- need to check and confirm.

Note, this is an effort to improve Tomcat servlet startup times.

add symlink to /Users/www/[project] in /var/www to access and serve local files

Hi,

I am trying to serve local CFML files on my mac via the docker container.
I got so far as to mount the specific folder on my mac to a symlink within my docker images

docker run -it imagesname 	-v /Users/[username]/www/projectx:/code /bin/bash

So on the bash in the docker image I now have /code.
I then create a symlink ln -s /code projectx in my /var/www

When I then serve the image running tomcat whilst also mounting the the folder

	docker run -p 1337:8888 -v /Users/[username]/www/projectx:/code [imagename] catalina.sh run

I would expect to be able to access http://localhost:1337/projectx
Unfortunately it can't find that folder. Probably sinces Lucee doesn't recognises/indexes the the files on run time?

Is this possible?

The outcome I am look at is developing my Coldfusion app on my MAC while running Lucee+mysql on my docker container and having the source code locally so that I don't have to play with samba shares or other ways to be able to edit the coldfusion files in my IDE.

Add preview tag for Lucee 5 beta

Create a preview tag for the latest Lucee 5 beta. Probably need a separate folder rather than branching. Config needs to rip out lucee4 java agent installation.

lucee/lucee52-nginx Missing Sample CFML page

Trying this container out and I am having issues. The sample page that is supposed to exist does not seem to. I get a 403 forbidden when trying to load the sample page or admin. I ssh'd in and found /var/www empty. I imagine im doing something wrong here.

My docker file is simply:

FROM lucee/lucee52-nginx:latest

And I have a docker-compose file to bring things up:

version: '3'
services:
  app:
    build: .
    ports:
     - "3000:80"
     - "3001:443"

Extensions are not consistently installed

In my Dockerfile, I have, among other things:

FROM lucee/lucee:5.3.7.47-nginx-tomcat9.0-jdk8-openjdk
ENV LUCEE_EXTENSIONS="99A4EF8D-F2FD-40C8-8FB8C2E67A4EEEB6;name=mssql_jdbc;version=7.2.2.jre8,66E312DD-D083-27C0-64189D16753FD6F0;name=pdf;version=1.0.0.94-SNAPSHOT"

When I start my container for the first time, I find that either one or both of the extensions I've requested has been installed. I need to have both be installed every time.

I wonder if maybe prewarm.sh isn't waiting long enough.

PS. I used to use ADD to download .lex files and place them in the deploy directory, but that doesn't seem to work since I upgraded from 5.3.3.67 to 5.3.7.47.

Add remote IP header; X-Forwarded-For

for the lucee base images we need to update the tomcat server.xml to add this inside the <Host> element:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
               remoteIpHeader="X-Forwarded-For"
               requestAttributesEnabled="true" />

Clarification on Tomcat Manager App

Apologies if this is more of a question than an issue:

I notice that logs get created in the image for the manager app. Though I cannot find it anywhere, is it running and accessible?

To work with various custom apps, I'm running the straight tomcat image behind httpd. I'm blocking /lucee, WEB-INF, and META-INF in httpd . . . should I be concerned about exposing the manager app?

Lucee 5.3

Lucee 5.3.1.95 has been released. What timeline should we expect for it to be integrated here ? Thanks.

/lucee/admin return a 404

I've setup the Lucee_nginx51 docker exactly as described here but cannot get the admin site to load. The sample "Hello Cruel World!" index.cfm page load fine. I've altered the default.conf file as follow:

location ~* /lucee/ { # allow 10.0.0.1; allow all; # deny all; }

Before I did that, I was getting a 403.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.