SAE runs applications as container images. If you don't have an existing image, follow the steps below to build one and push it to an image repository.
Prerequisites
Before you begin, make sure that you have:
Docker installed and running. Run
docker --versionto verify.A project directory with a built artifact (JAR, PHP files, Python app, or static assets).
Build and push a container image
Step 1: Create a Dockerfile
Navigate to your project directory and create a file named Dockerfile. The examples below cover Java, PHP, Python, and Node.js.
Java
Directory structure:
.
├── Dockerfile
├── target
│ └── my-app.jar # Compiled JAR — only this and the Dockerfile are needed to build the image
├── src
│ └── ...
└── pom.xmlDockerfile:
# Use an Alpine-based OpenJDK 8 image — Alpine keeps the image size small
FROM openjdk:8-jdk-alpine
# Copy the compiled JAR into the image root
COPY ./target/my-app.jar /
# Start the application when the container launches
ENTRYPOINT ["java", "-jar", "/my-app.jar"]Tip: For production Java applications, consider multi-stage builds to keep the final image lean: compile in a JDK stage, then copy only the JAR into a JRE-only runtime stage.
PHP
Directory structure:
.
├── Dockerfile
├── entrypoint.sh # Startup script that launches PHP-FPM and Nginx
├── php
│ ├── index.php
│ └── phpinfo.php
├── nginx
│ ├── nginx.conf
│ ├── conf.d
│ │ └── default.conf
│ ├── fastcgi_params
│ └── ...Dockerfile:
# Use an Alpine-based PHP-FPM image — PHP-FPM handles PHP processing, Nginx handles HTTP
FROM php:8.2-fpm-alpine
# Install Nginx into the same container to serve as the HTTP frontend
RUN apk add --no-cache nginx
# Copy Nginx configuration files
COPY nginx/ /etc/nginx/
# Copy PHP application files to the web root
COPY php/ /var/www/html/
# Copy and enable the startup script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Startup script (entrypoint.sh):
#!/bin/sh
# Start PHP-FPM in the background so Nginx can forward PHP requests to it
php-fpm -D
# Verify PHP-FPM started successfully before launching Nginx
if ! pgrep "php-fpm" >/dev/null
then
echo "PHP-FPM failed to start!"
exit 1
fi
# Run Nginx in the foreground — the container stays alive as long as Nginx runs
nginx -g "daemon off;"Python
Directory structure:
.
├── Dockerfile
├── entrypoint.sh
├── my_app
│ ├── requirements.txt
│ ├── main.py
│ └── my_package
│ ├── __init__.py
│ └── ...Dockerfile:
# Use the official Python 3.9 image
FROM python:3.9
# Copy the application code into the image
RUN mkdir -p /my_app
COPY my_app/ /my_app/
# Install Python dependencies declared in requirements.txt
RUN pip install -r /my_app/requirements.txt
# Copy and enable the startup script
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Startup script (entrypoint.sh):
#!/bin/sh
# Start the Flask app using Gunicorn with 3 worker processes, listening on port 8080
# Flask and Gunicorn are declared as dependencies in requirements.txt
gunicorn -w 3 -b 0.0.0.0:8080 my_app.main:appNode.js
This example covers a frontend project whose static assets are served by Nginx.
Directory structure:
.
├── Dockerfile
├── nginx-conf
│ ├── nginx.conf
│ ├── conf.d
│ │ └── default.conf
│ └── ...
├── package.json
├── src
│ └── ...
└── dist # Static files generated by your build step (e.g., npm run build)
├── index.html
└── static
└── ...Dockerfile:
# Use Nginx 1.22 as the base image — it provides the startup command, so no ENTRYPOINT is needed
FROM nginx:1.22
# Copy the built static files to Nginx's default serving directory
COPY ./dist /usr/share/nginx/html/
# Copy your Nginx configuration files
COPY ./nginx-conf /etc/nginx/Run your build step (for example,npm run build) before runningdocker build. Thedistdirectory must exist in your project root.
Step 2: Build the image
docker build -t <image-name>:<image-tag> .Example:
docker build -t my-app:1.0 .Do not hardcode secrets (API keys, passwords, or access credentials) in your Dockerfile using ENV or ARG. Values passed through build arguments can be exposed in the image history.
Step 3: Push the image to a repository
Push the image to an image repository that SAE can access. If you don't have one, use Alibaba Cloud Container Registry (ACR):
Step 4: Deploy to SAE
Choose the deployment method based on where your image is stored:
| Scenario | Method |
|---|---|
| Image is in ACR under the same Alibaba Cloud account | Deploy using ACR images from the same account |
| Image is in ACR under a different Alibaba Cloud account | Deploy using cross-account ACR images |
| Image is in a non-ACR repository | Deploy using images from a non-ACR repository |