Private projects use github action to package docker images and deploy them to servers
mrgao
Posted on June 1, 2023
There are always some projects that don't want to be open source. For the convenience of deployment, they hope to automatically deploy to different servers through docker after the code is changed. This article briefly describes the whole process, I hope it will help you
1. First create a project
First create a private project on github
Here we mainly take a front-end project as an example (a project created using umi)
mkdir myapp && cd myapp
pnpm dlx create-umi@latest
2. Talk about the basic commands of Docker
1. Common commands related to mirroring
# To download the mirror, first look for it from the local, did not go to the mirror, and finally did not go to the hub, if the label is not written, the default is latest
docker pull [image_name]:[image_tag]
# show all of images
docker image ls
docker images
# delete image file, -f force to delete
docker rmi [image_name][:Tag]
docker rmi [image_name1][:Tag1] [image_name2][:Tag2] # delete muti images
docker rmi $(docker ps -a -q) # delete all of images
# query the image name, --no-trunc displays the complete image description, --filter=stars=30 lists the images whose star is not less than the specified value, --filter=is-automated=true lists the images of the automatic build type
docker search [keyword]
# download the image, if the tag is not written, the default is latest, or you can add it yourself, for example: 3.2.0
docker pull [image_name1][:Tag]
2. Common commands related to containers
# list the running containers of this machine, -a lists all containers of this machine including the terminated container, -q silent mode only displays the container number, -l displays the most recently created container
docker container ls
docker ps
# create new container
docker run [option] [container_name]
# start container
docker start [container_id]/[container_name]
# restart container
docker restart [container_id]/[container_name]
docker stop [container_id] # stop container
docker stop $(docker ps -a -q) # stop all of containers
# remove container by id
docker rm [container_id]
docker rm `docker ps -aq`
# set the container to start automatically when docker starts
$ docker container update --restart=always [container_name]
I want to talk about docker run
it option
, because it is the most commonly used:
-
--name
specifies a name for the container; -
-d
The container enters the background after starting and returns the container ID, that is, starts the daemon container; -
-P
random port mapping; -
-p
80:8080 maps local port 80 to port 8080 of the container; -
-i
runs the container in interactive mode, usually used together with -t; -
-t
reassigns a pseudo-input terminal for the container, the shell of the container will be mapped to the current shell, and then the commands entered in the local window will be passed into the container, usually used together with -i; -
--rm
automatically deletes container files after the container terminates; -
--restart=always
set the container to start automatically; -
-v
/xxx:/yyy mapping command, map the xxx directory of the local machine to the yyy directory in the container, that is to say, if the content in the xxx directory of the local machine is changed, the content in the yyy directory of the container will also change;
3. Write Dockerfile
umi
Since the product will be placed dist
under the directory after the build, we can write the following Dockerfile;
Dockerfile is used to declare the steps of image execution; students who are not familiar with the following commands can click to view this article (opens new window)
FROM nginx:latest # use nginx to base image
LABEL maintainer "your github email"
ADD ./dist /usr/share/nginx/html # put the product in the /usr/share/nginx/html directory of nginx
EXPOSE 80 #
4. Write github action
Since only one private image is hub.docker.io
currently supported, we will not consider using it for the time being; it is recommended that you use github
the built-in image source ghcr.io
Preparatory work
- Go to https://github.com/settings/tokens to generate a token, note that this token needs permission to read and write packages, please see here for details (opens new window)
- Prepare the account number and password of your server to be deployed (the current page can use the secret key to log in, and the password is used here for now)
- Think about your image name (here we take web-image as an example)
In .github/workflows
the directory create apublish-image.yml
name: Publish Image
on:
push: # push to the main branch for automatic release
branches: ["main"]
paths-ignore: # ignore some unnecessary files
- ".gitignore"
- "README.md"
- ".vscode/**"
pull_request:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: docker/login-action@v1
with:
registry: ghcr.io # declare mirror source
username: ${{ github.actor }} # current github username
password: ${{ secrets.HUB_GITHUB_TOKEN }} # you need to go to https://github.com/settings/tokens to generate a token named token, note that this token requires permissions such as reading and writing packages
- uses: actions/setup-node@v2
with:
node-version: "16.14"
- uses: actions/cache@v2
id: cache
with:
path: node_modules
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# Runs a single command using the runners shell
- name: pnpm install
run: npm install -g pnpm
- name: Install
if: steps.cache.outputs.cache-hit != 'true'
run: pnpm i
- name: Build
run: npm run build
- name: Show Dir
run: ls
- name: Build the Docker image
run:
| # use the Dockerfile written in the previous step to build the image and publish it to the private warehouse; after the release is complete, you can go to https://github.com/your_github_name?tab=packages to view
docker build . --file Dockerfile --tag ghcr.io/your_github_name/web-image:latest
docker push ghcr.io/your_github_name/web-image:latest
- name: Update to Server
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }} # Server ip address; you need to go to the settings/secrets/actions of the warehouse to create
username: ${{ secrets.SERVER_USER }} # server username
password: ${{ secrets.SERVER_PWD }} # server password
port: ${{ secrets.SERVER_PORT }} # server port
script: | # Re-update the mirror and deploy
docker stop web-image
docker rm web-image
docker login -u your_github_name -p your_github_token https://ghcr.io
docker pull ghcr.io/your_github_name/web-image:latest
docker run -dp 80:80 --restart=always --name web-image ghcr.io/your_github_name/web-image
# The above uses port 80 to start, of course you can also change to the port you want
5. Private docker image
The private image we github
used ghcr
; of course, you can also create a private image based on docker/register; you can run the following command on your own server
# 1、download images
docker pull registry:2
# 2、run container
$ docker run -d --restart=always -v /opt/registry:/var/lib/registry -p 5000:5000 --name myregistry registry:2
Then build the image locally and upload the image:
# privatization build
$ docker build . --file Dockerfile --tag server_ip_address:5000:web-image:latest
# privatization push
$ docker push server_ip_address:5000:web-image:latest
# Note that an error was reported when uploading the image:http: server gave HTTP response to HTTPS client
# 【Execute on the client side of docker push, not the private server】Solution 1:
# 1、edit /etc/docker/daemon.json,write in the file: (if your image is actually on linux/centos)
{ "insecure-registries":["server_ip_address:5000"] }
# 【Execute on the client of docker push, not a private server】 or solution 2 (if your image is on linux/centos)
$ sudo vim /usr/lib/systemd/system/docker.service
# and change content
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock --insecure-registry server_ip_address:5000
# 2、restart server and docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
# push once
$ docker push server_ip_address:5000:web-image:latest
If you are using windows/mac, you can directly add it in the docker settings
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"experimental": false,
"features": {
"buildkit": true
},
"insecure-registries": ["server_ip_address:5000"]
}
Posted on June 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.